Changeset 28106 in webkit for trunk/JavaScriptCore
- Timestamp:
- Nov 28, 2007, 2:08:09 AM (18 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r28103 r28106 1 2007-11-28 Maciej Stachowiak <[email protected]> 2 3 Reviewed by Darin and Geoff. 4 5 - Fixed "Stack overflow crash in JavaScript garbage collector mark pass" 6 http://bugs.webkit.org/show_bug.cgi?id=12216 7 8 Implement mark stack. This version is not suitable for prime time because it makes a 9 huge allocation on every collect, and potentially makes marking of detached subtrees 10 slow. But it is an 0.4% SunSpider speedup even without much tweaking. 11 12 The basic approach is to replace mark() methods with 13 markChildren(MarkStack&) methods. Reachable references are pushed 14 onto a mark stack (which encapsulates ignoring already-marked 15 references). 16 17 Objects are no longer responsible for actually setting their own 18 mark bits, the collector does that. This means that for objects on 19 the number heap we don't have to call markChildren() at all since 20 we know there aren't any. 21 22 The mark phase of collect pushes roots onto the mark stack 23 and drains it as often as possible. 24 25 To make this approach viable requires a constant-size mark stack 26 and a slow fallback approach for when the stack size is exceeded, 27 plus optimizations to make the required stack small in common 28 cases. This should be doable. 29 30 * JavaScriptCore.exp: Export new symbols. 31 * JavaScriptCore.xcodeproj/project.pbxproj: Add new file. 32 * kjs/collector.cpp: 33 (KJS::Collector::heapAllocate): 34 (KJS::drainMarkStack): Helper for all of the below. 35 (KJS::Collector::markStackObjectsConservatively): Use mark stack. 36 (KJS::Collector::markCurrentThreadConservatively): ditto 37 (KJS::Collector::markOtherThreadConservatively): ditto 38 (KJS::Collector::markProtectedObjects): ditto 39 (KJS::Collector::markMainThreadOnlyObjects): ditto 40 (KJS::Collector::collect): ditto 41 * kjs/collector.h: 42 (KJS::Collector::cellMayHaveRefs): Helper for MarkStack. 43 44 * kjs/MarkStack.h: Added. The actual mark stack implementation. 45 (KJS::MarkStack::push): 46 (KJS::MarkStack::pushAtom): 47 (KJS::MarkStack::pop): 48 (KJS::MarkStack::isEmpty): 49 (KJS::MarkStack::reserveCapacity): 50 51 Changed mark() methods to markChildren() methods: 52 53 * kjs/ExecState.cpp: 54 (KJS::ExecState::markChildren): 55 * kjs/ExecState.h: 56 * kjs/JSWrapperObject.cpp: 57 (KJS::JSWrapperObject::markChildren): 58 * kjs/JSWrapperObject.h: 59 * kjs/array_instance.cpp: 60 (KJS::ArrayInstance::markChildren): 61 * kjs/array_instance.h: 62 * kjs/bool_object.cpp: 63 (BooleanInstance::markChildren): 64 * kjs/bool_object.h: 65 * kjs/error_object.cpp: 66 * kjs/error_object.h: 67 * kjs/function.cpp: 68 (KJS::FunctionImp::markChildren): 69 (KJS::Arguments::Arguments): 70 (KJS::Arguments::markChildren): 71 (KJS::ActivationImp::markChildren): 72 * kjs/function.h: 73 * kjs/internal.cpp: 74 (KJS::GetterSetterImp::markChildren): 75 * kjs/interpreter.cpp: 76 (KJS::Interpreter::markRoots): 77 * kjs/interpreter.h: 78 * kjs/list.cpp: 79 (KJS::List::markProtectedListsSlowCase): 80 * kjs/list.h: 81 (KJS::List::markProtectedLists): 82 * kjs/object.cpp: 83 (KJS::JSObject::markChildren): 84 * kjs/object.h: 85 (KJS::ScopeChain::markChildren): 86 * kjs/property_map.cpp: 87 (KJS::PropertyMap::markChildren): 88 * kjs/property_map.h: 89 * kjs/scope_chain.h: 90 * kjs/string_object.cpp: 91 (KJS::StringInstance::markChildren): 92 * kjs/string_object.h: 93 1 94 2007-11-27 Alp Toker <[email protected]> 2 95 -
trunk/JavaScriptCore/JavaScriptCore.exp
r27885 r28106 123 123 __ZN3KJS11Interpreter24setShouldPrintExceptionsEb 124 124 __ZN3KJS11Interpreter27resetGlobalObjectPropertiesEv 125 __ZN3KJS11Interpreter4markEv126 125 __ZN3KJS11Interpreter6s_hookE 127 126 __ZN3KJS11Interpreter8evaluateERKNS_7UStringEiPKNS_5UCharEiPNS_7JSValueE 128 127 __ZN3KJS11Interpreter8evaluateERKNS_7UStringEiS3_PNS_7JSValueE 128 __ZN3KJS11Interpreter9markRootsERNS_9MarkStackE 129 129 __ZN3KJS11InterpreterC1Ev 130 130 __ZN3KJS11InterpreterC2Ev … … 145 145 __ZN3KJS13SavedBuiltinsD1Ev 146 146 __ZN3KJS13jsOwnedStringERKNS_7UStringE 147 __ZN3KJS14StringInstance12markChildrenERNS_9MarkStackE 147 148 __ZN3KJS14StringInstance14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE 148 149 __ZN3KJS14StringInstance16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE … … 153 154 __ZN3KJS14StringInstanceC1EPNS_8JSObjectERKNS_7UStringE 154 155 __ZN3KJS14StringInstanceC2EPNS_8JSObjectERKNS_7UStringE 155 __ZN3KJS15JSWrapperObject4markEv156 156 __ZN3KJS15SavedPropertiesC1Ev 157 157 __ZN3KJS15SavedPropertiesD1Ev … … 202 202 __ZN3KJS8DebuggerD2Ev 203 203 __ZN3KJS8JSObject11hasInstanceEPNS_9ExecStateEPNS_7JSValueE 204 __ZN3KJS8JSObject12markChildrenERNS_9MarkStackE 204 205 __ZN3KJS8JSObject12removeDirectERKNS_10IdentifierE 205 206 __ZN3KJS8JSObject14callAsFunctionEPNS_9ExecStateEPS0_RKNS_4ListE … … 213 214 __ZN3KJS8JSObject3putEPNS_9ExecStateEjPNS_7JSValueEi 214 215 __ZN3KJS8JSObject4callEPNS_9ExecStateEPS0_RKNS_4ListE 215 __ZN3KJS8JSObject4markEv216 216 __ZN3KJS8JSObject9constructEPNS_9ExecStateERKNS_4ListE 217 217 __ZN3KJS8JSObject9constructEPNS_9ExecStateERKNS_4ListERKNS_10IdentifierERKNS_7UStringEi -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r27845 r28106 100 100 6592C319098B7DE10003D4F6 /* VectorTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 6592C317098B7DE10003D4F6 /* VectorTraits.h */; settings = {ATTRIBUTES = (Private, ); }; }; 101 101 65A7A5E00CD1D50E00061F8E /* LabelStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B813A80CD1D01900DF59D6 /* LabelStack.h */; settings = {ATTRIBUTES = (Private, ); }; }; 102 65A8B8DB0CF408F400DC7C27 /* MarkStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 65A8B8D80CF408E900DC7C27 /* MarkStack.h */; settings = {ATTRIBUTES = (Private, ); }; }; 102 103 65B1749A09D0FEB700820339 /* array_object.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B1749909D0FEB700820339 /* array_object.lut.h */; }; 103 104 65B174F509D100FA00820339 /* math_object.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B174F109D100FA00820339 /* math_object.lut.h */; }; … … 511 512 6592C316098B7DE10003D4F6 /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = "<group>"; }; 512 513 6592C317098B7DE10003D4F6 /* VectorTraits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VectorTraits.h; sourceTree = "<group>"; }; 514 65A8B8D80CF408E900DC7C27 /* MarkStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStack.h; sourceTree = "<group>"; }; 513 515 65B1749909D0FEB700820339 /* array_object.lut.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = file; name = array_object.lut.h; path = ../../../../../symroots/Debug/DerivedSources/JavaScriptCore/array_object.lut.h; sourceTree = "<group>"; }; 514 516 65B174BE09D1000200820339 /* chartables.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.c; fileEncoding = 30; path = chartables.c; sourceTree = "<group>"; }; … … 1009 1011 F692A8690255597D01FF60F7 /* lookup.h */, 1010 1012 F692A86A0255597D01FF60F7 /* math_object.cpp */, 1013 65A8B8D80CF408E900DC7C27 /* MarkStack.h */, 1011 1014 F692A86B0255597D01FF60F7 /* math_object.h */, 1012 1015 F692A86D0255597D01FF60F7 /* nodes.cpp */, … … 1171 1174 65F340940CD6C1C000C0CA8B /* LocalStorage.h in Headers */, 1172 1175 5DBD18B00C5401A700C15EAE /* MallocZoneSupport.h in Headers */, 1176 65A8B8DB0CF408F400DC7C27 /* MarkStack.h in Headers */, 1173 1177 BCF655590A2049710038A194 /* MathExtras.h in Headers */, 1174 1178 932F5B840822A1C700736975 /* NP_jsobject.h in Headers */, -
trunk/JavaScriptCore/kjs/ExecState.cpp
r27885 r28106 89 89 } 90 90 91 void ExecState::mark ()91 void ExecState::markChildren(MarkStack& stack) 92 92 { 93 93 for (ExecState* exec = this; exec; exec = exec->m_callingExecState) 94 exec->m_scopeChain.mark ();94 exec->m_scopeChain.markChildren(stack); 95 95 } 96 96 -
trunk/JavaScriptCore/kjs/ExecState.h
r27885 r28106 101 101 void setGlobalObject(JSGlobalObject*); 102 102 103 void mark ();103 void markChildren(MarkStack&); 104 104 105 105 // This is a workaround to avoid accessing the global variables for these identifiers in -
trunk/JavaScriptCore/kjs/JSWrapperObject.cpp
r15846 r28106 25 25 namespace KJS { 26 26 27 void JSWrapperObject::mark ()27 void JSWrapperObject::markChildren(MarkStack& stack) 28 28 { 29 JSObject::mark(); 30 if (m_internalValue && !m_internalValue->marked()) 31 m_internalValue->mark(); 29 JSObject::markChildren(stack); 30 stack.pushAtom(m_internalValue); 32 31 } 33 32 -
trunk/JavaScriptCore/kjs/JSWrapperObject.h
r15846 r28106 57 57 void setInternalValue(JSValue* v); 58 58 59 virtual void mark ();59 virtual void markChildren(MarkStack& stack); 60 60 61 61 private: … … 65 65 inline JSWrapperObject::JSWrapperObject(JSValue* proto) 66 66 : JSObject(proto) 67 , m_internalValue( 0)67 , m_internalValue(jsNull()) 68 68 { 69 69 } -
trunk/JavaScriptCore/kjs/array_instance.cpp
r27711 r28106 403 403 } 404 404 405 void ArrayInstance::mark ()406 { 407 JSObject::mark ();405 void ArrayInstance::markChildren(MarkStack& stack) 406 { 407 JSObject::markChildren(stack); 408 408 409 409 ArrayStorage* storage = m_storage; … … 412 412 for (unsigned i = 0; i < usedVectorLength; ++i) { 413 413 JSValue* value = storage->m_vector[i]; 414 if (value && !value->marked())415 value->mark();414 if (value) 415 stack.push(value); 416 416 } 417 417 418 418 if (SparseArrayValueMap* map = storage->m_sparseValueMap) { 419 419 SparseArrayValueMap::iterator end = map->end(); 420 for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) { 421 JSValue* value = it->second; 422 if (!value->marked()) 423 value->mark(); 424 } 420 for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) 421 stack.push(it->second); 425 422 } 426 423 } -
trunk/JavaScriptCore/kjs/array_instance.h
r26881 r28106 43 43 virtual void getPropertyNames(ExecState*, PropertyNameArray&); 44 44 45 virtual void mark ();45 virtual void markChildren(MarkStack&); 46 46 47 47 virtual const ClassInfo* classInfo() const { return &info; } -
trunk/JavaScriptCore/kjs/bool_object.cpp
r27448 r28106 37 37 : JSWrapperObject(proto) 38 38 { 39 } 40 41 void BooleanInstance::markChildren(MarkStack& stack) 42 { 43 JSObject::markChildren(stack); 44 ASSERT(JSImmediate::isImmediate(internalValue())); 39 45 } 40 46 -
trunk/JavaScriptCore/kjs/bool_object.h
r15846 r28106 33 33 34 34 virtual const ClassInfo *classInfo() const { return &info; } 35 virtual void markChildren(MarkStack& stack); 35 36 static const ClassInfo info; 36 37 }; -
trunk/JavaScriptCore/kjs/collector.cpp
r27574 r28106 27 27 #include "internal.h" 28 28 #include "list.h" 29 #include "MarkStack.h" 29 30 #include "value.h" 30 31 #include <algorithm> … … 278 279 targetBlock = (Block*)allocateBlock(); 279 280 targetBlock->freeList = targetBlock->cells; 281 if (heapType == PrimaryHeap) 282 targetBlock->mayHaveRefs = 1; 280 283 targetBlockUsedCells = 0; 281 284 heap.blocks[usedBlocks] = (CollectorBlock*)targetBlock; … … 480 483 #define IS_HALF_CELL_ALIGNED(p) (((intptr_t)(p) & (CELL_MASK >> 1)) == 0) 481 484 482 void Collector::markStackObjectsConservatively(void *start, void *end) 485 static inline void drainMarkStack(MarkStack& stack) 486 { 487 while (!stack.isEmpty()) 488 stack.pop()->markChildren(stack); 489 } 490 491 492 void Collector::markStackObjectsConservatively(MarkStack& stack, void *start, void *end) 483 493 { 484 494 if (start > end) { … … 522 532 if (((CollectorCell*)xAsBits)->u.freeCell.zeroIfFree != 0) { 523 533 JSCell* imp = reinterpret_cast<JSCell*>(xAsBits); 524 if (!imp->marked())525 imp->mark();534 stack.push(imp); 535 drainMarkStack(stack); 526 536 } 527 537 break; … … 534 544 } 535 545 536 void Collector::markCurrentThreadConservatively( )546 void Collector::markCurrentThreadConservatively(MarkStack& stack) 537 547 { 538 548 // setjmp forces volatile registers onto the stack … … 551 561 void* stackBase = currentThreadStackBase(); 552 562 553 markStackObjectsConservatively(stack Pointer, stackBase);563 markStackObjectsConservatively(stack, stackPointer, stackBase); 554 564 } 555 565 … … 694 704 } 695 705 696 void Collector::markOtherThreadConservatively( Thread* thread)706 void Collector::markOtherThreadConservatively(MarkStack& stack, Thread* thread) 697 707 { 698 708 suspendThread(thread->platformThread); … … 702 712 703 713 // mark the thread's registers 704 markStackObjectsConservatively( (void*)®s, (void*)((char*)®s + regSize));714 markStackObjectsConservatively(stack, (void*)®s, (void*)((char*)®s + regSize)); 705 715 706 716 void* stackPointer = otherThreadStackPointer(regs); 707 717 void* stackBase = otherThreadStackBase(regs, thread); 708 markStackObjectsConservatively(stack Pointer, stackBase);718 markStackObjectsConservatively(stack, stackPointer, stackBase); 709 719 710 720 resumeThread(thread->platformThread); … … 713 723 #endif 714 724 715 void Collector::markStackObjectsConservatively( )716 { 717 markCurrentThreadConservatively( );725 void Collector::markStackObjectsConservatively(MarkStack& stack) 726 { 727 markCurrentThreadConservatively(stack); 718 728 719 729 #if USE(MULTIPLE_THREADS) 720 730 for (Thread *thread = registeredThreads; thread != NULL; thread = thread->next) { 721 731 if (!pthread_equal(thread->posixThread, pthread_self())) { 722 markOtherThreadConservatively(thread);732 markOtherThreadConservatively(stack, thread); 723 733 } 724 734 } … … 772 782 } 773 783 774 void Collector::markProtectedObjects( )784 void Collector::markProtectedObjects(MarkStack& stack) 775 785 { 776 786 ProtectCountSet& protectedValues = KJS::protectedValues(); 777 787 ProtectCountSet::iterator end = protectedValues.end(); 778 788 for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it) { 779 JSCell *val = it->first; 780 if (!val->marked()) 781 val->mark(); 782 } 783 } 784 785 void Collector::markMainThreadOnlyObjects() 789 stack.push(it->first); 790 drainMarkStack(stack); 791 } 792 } 793 794 void Collector::markMainThreadOnlyObjects(MarkStack& stack) 786 795 { 787 796 #if USE(MULTIPLE_THREADS) … … 815 824 if (!curBlock->marked.get(i)) { 816 825 JSCell* imp = reinterpret_cast<JSCell*>(cell); 817 imp->mark(); 826 stack.push(imp); 827 drainMarkStack(stack); 818 828 } 819 829 if (++count == mainThreadOnlyObjectCount) … … 951 961 // MARK: first mark all referenced objects recursively starting out from the set of root objects 952 962 963 size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects; 964 965 MarkStack stack; 966 stack.reserveCapacity(primaryHeap.numLiveObjects); 967 953 968 #ifndef NDEBUG 954 969 // Forbid malloc during the mark phase. Marking a thread suspends it, so 955 // a malloc inside mark () would risk a deadlock with a thread that had been970 // a malloc inside markChildren() would risk a deadlock with a thread that had been 956 971 // suspended while holding the malloc lock. 957 972 fastMallocForbid(); … … 961 976 Interpreter* scr = Interpreter::s_hook; 962 977 do { 963 scr->mark(); 978 scr->markRoots(stack); 979 drainMarkStack(stack); 964 980 scr = scr->next; 965 981 } while (scr != Interpreter::s_hook); 966 982 } 967 983 968 markStackObjectsConservatively(); 969 markProtectedObjects(); 970 List::markProtectedLists(); 984 markStackObjectsConservatively(stack); 985 markProtectedObjects(stack); 986 List::markProtectedLists(stack); 987 drainMarkStack(stack); 971 988 #if USE(MULTIPLE_THREADS) 972 989 if (!currentThreadIsMainThread) 973 markMainThreadOnlyObjects( );990 markMainThreadOnlyObjects(stack); 974 991 #endif 975 992 … … 978 995 #endif 979 996 980 size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects;981 997 size_t numLiveObjects = sweep<PrimaryHeap>(currentThreadIsMainThread); 982 998 numLiveObjects += sweep<NumberHeap>(currentThreadIsMainThread); -
trunk/JavaScriptCore/kjs/collector.h
r27298 r28106 32 32 namespace KJS { 33 33 34 class CollectorBlock; 34 35 class JSCell; 35 36 class JSValue; 36 class CollectorBlock;37 class MarkStack; 37 38 38 39 class Collector { … … 66 67 static bool isCellMarked(const JSCell*); 67 68 static void markCell(JSCell*); 69 static bool cellMayHaveRefs(const JSCell*); 68 70 69 71 enum HeapType { PrimaryHeap, NumberHeap }; … … 79 81 80 82 static void recordExtraCost(size_t); 81 static void markProtectedObjects( );82 static void markMainThreadOnlyObjects( );83 static void markCurrentThreadConservatively( );84 static void markOtherThreadConservatively( Thread*);85 static void markStackObjectsConservatively( );86 static void markStackObjectsConservatively( void* start, void* end);83 static void markProtectedObjects(MarkStack&); 84 static void markMainThreadOnlyObjects(MarkStack&); 85 static void markCurrentThreadConservatively(MarkStack&); 86 static void markOtherThreadConservatively(MarkStack&, Thread*); 87 static void markStackObjectsConservatively(MarkStack&); 88 static void markStackObjectsConservatively(MarkStack&, void* start, void* end); 87 89 88 90 static size_t mainThreadOnlyObjectCount; … … 108 110 const size_t CELL_MASK = CELL_SIZE - 1; 109 111 const size_t CELL_ALIGN_MASK = ~CELL_MASK; 110 const size_t CELLS_PER_BLOCK = (BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof( void *) * 8 - 2 * (7 + 3 * 8)) / (CELL_SIZE * 8 + 2);112 const size_t CELLS_PER_BLOCK = (BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof(uint32_t) * 8 - sizeof(void *) * 8 - 2 * (7 + 3 * 8)) / (CELL_SIZE * 8 + 2); 111 113 const size_t SMALL_CELLS_PER_BLOCK = 2 * CELLS_PER_BLOCK; 112 114 const size_t BITMAP_SIZE = (CELLS_PER_BLOCK + 7) / 8; … … 146 148 uint32_t usedCells; 147 149 CollectorCell* freeList; 150 uint32_t mayHaveRefs; 148 151 CollectorBitmap marked; 149 152 CollectorBitmap collectOnMainThreadOnly; … … 155 158 uint32_t usedCells; 156 159 SmallCollectorCell* freeList; 160 uint32_t mayHaveRefs; 157 161 CollectorBitmap marked; 158 162 CollectorBitmap collectOnMainThreadOnly; … … 182 186 { 183 187 cellBlock(cell)->marked.set(cellOffset(cell)); 188 } 189 190 inline bool Collector::cellMayHaveRefs(const JSCell* cell) 191 { 192 return cellBlock(cell)->mayHaveRefs; 184 193 } 185 194 -
trunk/JavaScriptCore/kjs/error_object.cpp
r27413 r28106 157 157 } 158 158 159 void NativeErrorImp::mark()160 {161 JSObject::mark();162 if (proto && !proto->marked())163 proto->mark();164 } -
trunk/JavaScriptCore/kjs/error_object.h
r13821 r28106 76 76 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); 77 77 78 virtual void mark();79 80 78 virtual const ClassInfo *classInfo() const { return &info; } 81 79 static const ClassInfo info; -
trunk/JavaScriptCore/kjs/function.cpp
r28053 r28106 62 62 } 63 63 64 void FunctionImp::mark ()65 { 66 InternalFunctionImp::mark ();67 _scope.mark ();64 void FunctionImp::markChildren(MarkStack& stack) 65 { 66 InternalFunctionImp::markChildren(stack); 67 _scope.markChildren(stack); 68 68 } 69 69 … … 332 332 // ECMA 10.1.8 333 333 Arguments::Arguments(ExecState* exec, FunctionImp* func, const List& args, ActivationImp* act) 334 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()),335 _activationObject(act), 336 indexToNameMap(func, args)334 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()) 335 , _activationObject(act) 336 , indexToNameMap(func, args) 337 337 { 338 338 putDirect(exec->propertyNames().callee, func, DontEnum); … … 348 348 } 349 349 350 void Arguments::mark() 351 { 352 JSObject::mark(); 353 if (_activationObject && !_activationObject->marked()) 354 _activationObject->mark(); 350 void Arguments::markChildren(MarkStack& stack) 351 { 352 JSObject::markChildren(stack); 353 stack.push(_activationObject); 355 354 } 356 355 … … 485 484 } 486 485 487 void ActivationImp::mark ()488 { 489 JSObject::mark ();486 void ActivationImp::markChildren(MarkStack& stack) 487 { 488 JSObject::markChildren(stack); 490 489 491 490 size_t size = d->localStorage.size(); 492 for (size_t i = 0; i < size; ++i) { 493 JSValue* value = d->localStorage[i].value; 494 if (!value->marked()) 495 value->mark(); 496 } 491 for (size_t i = 0; i < size; ++i) 492 stack.push(d->localStorage[i].value); 497 493 498 ASSERT(d->function); 499 if (!d->function->marked()) 500 d->function->mark(); 501 502 if (d->argumentsObject && !d->argumentsObject->marked()) 503 d->argumentsObject->mark(); 494 stack.push(d->function); 495 if (d->argumentsObject) 496 stack.push(d->argumentsObject); 504 497 } 505 498 -
trunk/JavaScriptCore/kjs/function.h
r28053 r28106 96 96 const ScopeChain& scope() const { return _scope; } 97 97 98 virtual void mark ();98 virtual void markChildren(MarkStack&); 99 99 100 100 private: … … 125 125 public: 126 126 Arguments(ExecState*, FunctionImp* func, const List& args, ActivationImp* act); 127 virtual void mark ();127 virtual void markChildren(MarkStack&); 128 128 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 129 129 virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, int attr = None); … … 165 165 static const ClassInfo info; 166 166 167 virtual void mark ();167 virtual void markChildren(MarkStack&); 168 168 169 169 bool isActivation() { return true; } -
trunk/JavaScriptCore/kjs/internal.cpp
r27695 r28106 145 145 146 146 // --------------------------- GetterSetterImp --------------------------------- 147 void GetterSetterImp::mark() 148 { 149 JSCell::mark(); 150 151 if (getter && !getter->marked()) 152 getter->mark(); 153 if (setter && !setter->marked()) 154 setter->mark(); 147 void GetterSetterImp::markChildren(MarkStack& stack) 148 { 149 if (getter) 150 stack.push(getter); 151 if (setter) 152 stack.push(setter); 155 153 } 156 154 -
trunk/JavaScriptCore/kjs/interpreter.cpp
r27885 r28106 545 545 } 546 546 547 void Interpreter::mark ()547 void Interpreter::markRoots(MarkStack& stack) 548 548 { 549 549 if (m_currentExec) 550 m_currentExec->mark ();551 552 if (m_globalExec.exception() && !m_globalExec.exception()->marked())553 m_globalExec.exception()->mark();554 555 if (m_globalObject && !m_globalObject->marked())556 m_globalObject->mark();557 558 if (m_Object && !m_Object->marked())559 m_Object->mark();560 if (m_Function && !m_Function->marked())561 m_Function->mark();562 if (m_Array && !m_Array->marked())563 m_Array->mark();564 if (m_Boolean && !m_Boolean->marked())565 m_Boolean->mark();566 if (m_String && !m_String->marked())567 m_String->mark();568 if (m_Number && !m_Number->marked())569 m_Number->mark();570 if (m_Date && !m_Date->marked())571 m_Date->mark();572 if (m_RegExp && !m_RegExp->marked())573 m_RegExp->mark();574 if (m_Error && !m_Error->marked())575 m_Error->mark();576 577 if (m_ObjectPrototype && !m_ObjectPrototype->marked())578 m_ObjectPrototype->mark();579 if (m_FunctionPrototype && !m_FunctionPrototype->marked())580 m_FunctionPrototype->mark();581 if (m_ArrayPrototype && !m_ArrayPrototype->marked())582 m_ArrayPrototype->mark();583 if (m_BooleanPrototype && !m_BooleanPrototype->marked())584 m_BooleanPrototype->mark();585 if (m_StringPrototype && !m_StringPrototype->marked())586 m_StringPrototype->mark();587 if (m_NumberPrototype && !m_NumberPrototype->marked())588 m_NumberPrototype->mark();589 if (m_DatePrototype && !m_DatePrototype->marked())590 m_DatePrototype->mark();591 if (m_RegExpPrototype && !m_RegExpPrototype->marked())592 m_RegExpPrototype->mark();593 if (m_ErrorPrototype && !m_ErrorPrototype->marked())594 m_ErrorPrototype->mark();595 596 if (m_EvalError && !m_EvalError->marked())597 m_EvalError->mark();598 if (m_RangeError && !m_RangeError->marked())599 m_RangeError->mark();600 if (m_ReferenceError && !m_ReferenceError->marked())601 m_ReferenceError->mark();602 if (m_SyntaxError && !m_SyntaxError->marked())603 m_SyntaxError->mark();604 if (m_TypeError && !m_TypeError->marked())605 m_TypeError->mark();606 if (m_UriError && !m_UriError->marked())607 m_UriError->mark();608 609 if (m_EvalErrorPrototype && !m_EvalErrorPrototype->marked())610 m_EvalErrorPrototype->mark();611 if (m_RangeErrorPrototype && !m_RangeErrorPrototype->marked())612 m_RangeErrorPrototype->mark();613 if (m_ReferenceErrorPrototype && !m_ReferenceErrorPrototype->marked())614 m_ReferenceErrorPrototype->mark();615 if (m_SyntaxErrorPrototype && !m_SyntaxErrorPrototype->marked())616 m_SyntaxErrorPrototype->mark();617 if (m_TypeErrorPrototype && !m_TypeErrorPrototype->marked())618 m_TypeErrorPrototype->mark();619 if (m_UriErrorPrototype && !m_UriErrorPrototype->marked())620 m_UriErrorPrototype->mark();550 m_currentExec->markChildren(stack); 551 552 if (m_globalExec.exception()) 553 stack.push(m_globalExec.exception()); 554 555 if (m_globalObject) 556 stack.push(m_globalObject); 557 558 if (m_Object) 559 stack.push(m_Object); 560 if (m_Function) 561 stack.push(m_Function); 562 if (m_Array) 563 stack.push(m_Array); 564 if (m_Boolean) 565 stack.push(m_Boolean); 566 if (m_String) 567 stack.push(m_String); 568 if (m_Number) 569 stack.push(m_Number); 570 if (m_Date) 571 stack.push(m_Date); 572 if (m_RegExp) 573 stack.push(m_RegExp); 574 if (m_Error) 575 stack.push(m_Error); 576 577 if (m_ObjectPrototype) 578 stack.push(m_ObjectPrototype); 579 if (m_FunctionPrototype) 580 stack.push(m_FunctionPrototype); 581 if (m_ArrayPrototype) 582 stack.push(m_ArrayPrototype); 583 if (m_BooleanPrototype) 584 stack.push(m_BooleanPrototype); 585 if (m_StringPrototype) 586 stack.push(m_StringPrototype); 587 if (m_NumberPrototype) 588 stack.push(m_NumberPrototype); 589 if (m_DatePrototype) 590 stack.push(m_DatePrototype); 591 if (m_RegExpPrototype) 592 stack.push(m_RegExpPrototype); 593 if (m_ErrorPrototype) 594 stack.push(m_ErrorPrototype); 595 596 if (m_EvalError) 597 stack.push(m_EvalError); 598 if (m_RangeError) 599 stack.push(m_RangeError); 600 if (m_ReferenceError) 601 stack.push(m_ReferenceError); 602 if (m_SyntaxError) 603 stack.push(m_SyntaxError); 604 if (m_TypeError) 605 stack.push(m_TypeError); 606 if (m_UriError) 607 stack.push(m_UriError); 608 609 if (m_EvalErrorPrototype) 610 stack.push(m_EvalErrorPrototype); 611 if (m_RangeErrorPrototype) 612 stack.push(m_RangeErrorPrototype); 613 if (m_ReferenceErrorPrototype) 614 stack.push(m_ReferenceErrorPrototype); 615 if (m_SyntaxErrorPrototype) 616 stack.push(m_SyntaxErrorPrototype); 617 if (m_TypeErrorPrototype) 618 stack.push(m_TypeErrorPrototype); 619 if (m_UriErrorPrototype) 620 stack.push(m_UriErrorPrototype); 621 621 } 622 622 -
trunk/JavaScriptCore/kjs/interpreter.h
r27885 r28106 291 291 * implementing custom mark methods must make sure to chain to this one. 292 292 */ 293 virtual void mark ();293 virtual void markRoots(MarkStack&); 294 294 295 295 static bool shouldPrintExceptions(); -
trunk/JavaScriptCore/kjs/list.cpp
r27453 r28106 44 44 } 45 45 46 void List::markProtectedListsSlowCase( )46 void List::markProtectedListsSlowCase(MarkStack& stack) 47 47 { 48 48 ListSet::iterator end = markSet().end(); … … 51 51 52 52 iterator end2 = list->end(); 53 for (iterator it2 = list->begin(); it2 != end2; ++it2) { 54 JSValue* v = *it2; 55 if (!v->marked()) 56 v->mark(); 57 } 53 for (iterator it2 = list->begin(); it2 != end2; ++it2) 54 stack.push(*it2); 58 55 } 59 56 } -
trunk/JavaScriptCore/kjs/list.h
r27472 r28106 86 86 const_iterator end() const { return m_vector.end(); } 87 87 88 static void markProtectedLists( )88 static void markProtectedLists(MarkStack& stack) 89 89 { 90 90 if (!markSet().size()) 91 91 return; 92 markProtectedListsSlowCase( );92 markProtectedListsSlowCase(stack); 93 93 } 94 94 … … 97 97 private: 98 98 static ListSet& markSet(); 99 static void markProtectedListsSlowCase( );99 static void markProtectedListsSlowCase(MarkStack&); 100 100 101 101 void expandAndAppend(JSValue*); -
trunk/JavaScriptCore/kjs/object.cpp
r27695 r28106 114 114 // ------------------------------ JSObject ------------------------------------ 115 115 116 void JSObject::mark() 117 { 118 JSCell::mark(); 119 116 void JSObject::markChildren(MarkStack& stack) 117 { 120 118 #if JAVASCRIPT_MARK_TRACING 121 119 static int markStackDepth = 0; … … 127 125 #endif 128 126 129 JSValue *proto = _proto; 130 if (!proto->marked()) 131 proto->mark(); 132 133 _prop.mark(); 127 stack.push(_proto); 128 _prop.markChildren(stack); 134 129 135 130 #if JAVASCRIPT_MARK_TRACING -
trunk/JavaScriptCore/kjs/object.h
r27695 r28106 28 28 #include "JSType.h" 29 29 #include "CommonIdentifiers.h" 30 #include "MarkStack.h" 30 31 #include "interpreter.h" 31 32 #include "property_map.h" … … 85 86 virtual JSObject *toObject(ExecState *exec) const; 86 87 87 virtual void mark ();88 virtual void markChildren(MarkStack&); 88 89 89 90 JSObject *getGetter() { return getter; } … … 112 113 JSObject(); 113 114 114 virtual void mark ();115 virtual void markChildren(MarkStack&); 115 116 virtual JSType type() const; 116 117 … … 587 588 // FIXME: Put this function in a separate file named something like scope_chain_mark.h -- can't put it in scope_chain.h since it depends on JSObject. 588 589 589 inline void ScopeChain::mark() 590 { 591 for (ScopeChainNode *n = _node; n; n = n->next) { 592 JSObject *o = n->object; 593 if (!o->marked()) 594 o->mark(); 590 inline void ScopeChain::markChildren(MarkStack& stack) 591 { 592 for (ScopeChainNode* n = _node; n; n = n->next) { 593 JSObject* o = n->object; 594 stack.push(o); 595 595 } 596 596 } -
trunk/JavaScriptCore/kjs/property_map.cpp
r27711 r28106 623 623 } 624 624 625 void PropertyMap::mark() const 626 { 627 if (!m_usingTable) { 628 #if USE_SINGLE_ENTRY 629 if (m_singleEntryKey) { 630 JSValue* v = m_u.singleEntryValue; 631 if (!v->marked()) 632 v->mark(); 633 } 625 void PropertyMap::markChildren(MarkStack& stack) const 626 { 627 if (!m_usingTable) { 628 #if USE_SINGLE_ENTRY 629 if (m_singleEntryKey) 630 stack.push(m_u.singleEntryValue); 634 631 #endif 635 632 return; … … 637 634 638 635 unsigned entryCount = m_u.table->keyCount + m_u.table->deletedSentinelCount; 639 for (unsigned i = 1; i <= entryCount; i++) { 640 JSValue* v = m_u.table->entries()[i].value; 641 if (!v->marked()) 642 v->mark(); 643 } 636 for (unsigned i = 1; i <= entryCount; i++) 637 stack.push(m_u.table->entries()[i].value); 644 638 } 645 639 -
trunk/JavaScriptCore/kjs/property_map.h
r27387 r28106 30 30 class JSObject; 31 31 class JSValue; 32 class MarkStack; 32 33 class PropertyNameArray; 33 34 … … 60 61 JSValue** getLocation(const Identifier& name); 61 62 62 void mark () const;63 void markChildren(MarkStack&) const; 63 64 void getEnumerablePropertyNames(PropertyNameArray&) const; 64 65 -
trunk/JavaScriptCore/kjs/scope_chain.h
r28079 r28106 83 83 void pop(); 84 84 85 void mark ();85 void markChildren(MarkStack&); 86 86 87 87 #ifndef NDEBUG -
trunk/JavaScriptCore/kjs/string_object.cpp
r27633 r28106 128 128 propertyNames.add(Identifier(UString::from(i))); 129 129 return JSObject::getPropertyNames(exec, propertyNames); 130 } 131 132 void StringInstance::markChildren(MarkStack& stack) 133 { 134 JSObject::markChildren(stack); 135 stack.pushAtom(internalValue()); 130 136 } 131 137 -
trunk/JavaScriptCore/kjs/string_object.h
r27608 r28106 47 47 48 48 StringImp* internalValue() const { return static_cast<StringImp*>(JSWrapperObject::internalValue());} 49 virtual void markChildren(MarkStack& stack); 49 50 50 51 private: -
trunk/JavaScriptCore/kjs/value.h
r27747 r28106 34 34 class JSObject; 35 35 class JSCell; 36 class MarkStack; 36 37 37 38 struct ClassInfo; … … 48 49 friend class JSCell; // so it can derive from this class 49 50 friend class Collector; // so it can call asCell() 51 friend class MarkStack; // so it can call asCell() 50 52 51 53 private: … … 106 108 107 109 // Garbage collection. 108 void mark ();110 void markChildren(MarkStack&); 109 111 bool marked() const; 110 112 … … 165 167 // Garbage collection. 166 168 void *operator new(size_t); 167 virtual void mark ();169 virtual void markChildren(MarkStack&); 168 170 bool marked() const; 169 171 }; … … 291 293 } 292 294 293 inline void JSCell::mark() 294 { 295 return Collector::markCell(this); 295 inline void JSCell::markChildren(MarkStack&) 296 { 296 297 } 297 298 … … 407 408 } 408 409 409 inline void JSValue::mark ()410 { 411 ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling mark ()412 asCell()->mark ();410 inline void JSValue::markChildren(MarkStack& stack) 411 { 412 ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling markChildren() 413 asCell()->markChildren(stack); 413 414 } 414 415
Note:
See TracChangeset
for help on using the changeset viewer.