Changeset 28110 in webkit for trunk/JavaScriptCore
- Timestamp:
- Nov 28, 2007, 5:12:03 AM (18 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 1 deleted
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r28108 r28110 1 2007-11-28 Maciej Stachowiak <[email protected]>2 3 Add files missing from previous commit.4 5 * kjs/MarkStack.h: Added.6 7 2007-11-28 Maciej Stachowiak <[email protected]>8 9 Not reviewed.10 11 - Fixed "Stack overflow crash in JavaScript garbage collector mark pass"12 http://bugs.webkit.org/show_bug.cgi?id=1221613 14 Implement mark stack. This version is not suitable for prime time because it makes a15 huge allocation on every collect, and potentially makes marking of detached subtrees16 slow. But it is a .2% - .4% speedup even without much tweaking.17 18 The basic approach is to replace mark() methods with19 markChildren(MarkStack&) methods. Reachable references are pushed20 onto a mark stack (which encapsulates ignoring already-marked21 references).22 23 Objects are no longer responsible for actually setting their own24 mark bits, the collector does that. This means that for objects on25 the number heap we don't have to call markChildren() at all since26 we know there aren't any.27 28 The mark phase of collect pushes roots onto the mark stack29 and drains it as often as possible.30 31 To make this approach viable requires a constant-size mark stack32 and a slow fallback approach for when the stack size is exceeded,33 plus optimizations to make the required stack small in common34 cases. This should be doable.35 36 * JavaScriptCore.exp: Export new symbols.37 * JavaScriptCore.xcodeproj/project.pbxproj: Add new file.38 * kjs/collector.cpp:39 (KJS::Collector::heapAllocate):40 (KJS::drainMarkStack): Helper for all of the below.41 (KJS::Collector::markStackObjectsConservatively): Use mark stack.42 (KJS::Collector::markCurrentThreadConservatively): ditto43 (KJS::Collector::markOtherThreadConservatively): ditto44 (KJS::Collector::markProtectedObjects): ditto45 (KJS::Collector::markMainThreadOnlyObjects): ditto46 (KJS::Collector::collect): ditto47 * kjs/collector.h:48 (KJS::Collector::cellMayHaveRefs): Helper for MarkStack.49 50 * kjs/MarkStack.h: Added. The actual mark stack implementation.51 (KJS::MarkStack::push):52 (KJS::MarkStack::pushAtom):53 (KJS::MarkStack::pop):54 (KJS::MarkStack::isEmpty):55 (KJS::MarkStack::reserveCapacity):56 57 Changed mark() methods to markChildren() methods:58 59 * kjs/ExecState.cpp:60 (KJS::ExecState::markChildren):61 * kjs/ExecState.h:62 * kjs/JSWrapperObject.cpp:63 (KJS::JSWrapperObject::markChildren):64 * kjs/JSWrapperObject.h:65 * kjs/array_instance.cpp:66 (KJS::ArrayInstance::markChildren):67 * kjs/array_instance.h:68 * kjs/bool_object.cpp:69 (BooleanInstance::markChildren):70 * kjs/bool_object.h:71 * kjs/error_object.cpp:72 * kjs/error_object.h:73 * kjs/function.cpp:74 (KJS::FunctionImp::markChildren):75 (KJS::Arguments::Arguments):76 (KJS::Arguments::markChildren):77 (KJS::ActivationImp::markChildren):78 * kjs/function.h:79 * kjs/internal.cpp:80 (KJS::GetterSetterImp::markChildren):81 * kjs/interpreter.cpp:82 (KJS::Interpreter::markRoots):83 * kjs/interpreter.h:84 * kjs/list.cpp:85 (KJS::List::markProtectedListsSlowCase):86 * kjs/list.h:87 (KJS::List::markProtectedLists):88 * kjs/object.cpp:89 (KJS::JSObject::markChildren):90 * kjs/object.h:91 (KJS::ScopeChain::markChildren):92 * kjs/property_map.cpp:93 (KJS::PropertyMap::markChildren):94 * kjs/property_map.h:95 * kjs/scope_chain.h:96 * kjs/string_object.cpp:97 (KJS::StringInstance::markChildren):98 * kjs/string_object.h:99 100 2007-11-28 Maciej Stachowiak <[email protected]>101 102 Reviewed by Darin and Geoff.103 104 - Fixed "Stack overflow crash in JavaScript garbage collector mark pass"105 http://bugs.webkit.org/show_bug.cgi?id=12216106 107 Implement mark stack. This version is not suitable for prime time because it makes a108 huge allocation on every collect, and potentially makes marking of detached subtrees109 slow. But it is an 0.4% SunSpider speedup even without much tweaking.110 111 The basic approach is to replace mark() methods with112 markChildren(MarkStack&) methods. Reachable references are pushed113 onto a mark stack (which encapsulates ignoring already-marked114 references).115 116 Objects are no longer responsible for actually setting their own117 mark bits, the collector does that. This means that for objects on118 the number heap we don't have to call markChildren() at all since119 we know there aren't any.120 121 The mark phase of collect pushes roots onto the mark stack122 and drains it as often as possible.123 124 To make this approach viable requires a constant-size mark stack125 and a slow fallback approach for when the stack size is exceeded,126 plus optimizations to make the required stack small in common127 cases. This should be doable.128 129 * JavaScriptCore.exp: Export new symbols.130 * JavaScriptCore.xcodeproj/project.pbxproj: Add new file.131 * kjs/collector.cpp:132 (KJS::Collector::heapAllocate):133 (KJS::drainMarkStack): Helper for all of the below.134 (KJS::Collector::markStackObjectsConservatively): Use mark stack.135 (KJS::Collector::markCurrentThreadConservatively): ditto136 (KJS::Collector::markOtherThreadConservatively): ditto137 (KJS::Collector::markProtectedObjects): ditto138 (KJS::Collector::markMainThreadOnlyObjects): ditto139 (KJS::Collector::collect): ditto140 * kjs/collector.h:141 (KJS::Collector::cellMayHaveRefs): Helper for MarkStack.142 143 * kjs/MarkStack.h: Added. The actual mark stack implementation.144 (KJS::MarkStack::push):145 (KJS::MarkStack::pushAtom):146 (KJS::MarkStack::pop):147 (KJS::MarkStack::isEmpty):148 (KJS::MarkStack::reserveCapacity):149 150 Changed mark() methods to markChildren() methods:151 152 * kjs/ExecState.cpp:153 (KJS::ExecState::markChildren):154 * kjs/ExecState.h:155 * kjs/JSWrapperObject.cpp:156 (KJS::JSWrapperObject::markChildren):157 * kjs/JSWrapperObject.h:158 * kjs/array_instance.cpp:159 (KJS::ArrayInstance::markChildren):160 * kjs/array_instance.h:161 * kjs/bool_object.cpp:162 (BooleanInstance::markChildren):163 * kjs/bool_object.h:164 * kjs/error_object.cpp:165 * kjs/error_object.h:166 * kjs/function.cpp:167 (KJS::FunctionImp::markChildren):168 (KJS::Arguments::Arguments):169 (KJS::Arguments::markChildren):170 (KJS::ActivationImp::markChildren):171 * kjs/function.h:172 * kjs/internal.cpp:173 (KJS::GetterSetterImp::markChildren):174 * kjs/interpreter.cpp:175 (KJS::Interpreter::markRoots):176 * kjs/interpreter.h:177 * kjs/list.cpp:178 (KJS::List::markProtectedListsSlowCase):179 * kjs/list.h:180 (KJS::List::markProtectedLists):181 * kjs/object.cpp:182 (KJS::JSObject::markChildren):183 * kjs/object.h:184 (KJS::ScopeChain::markChildren):185 * kjs/property_map.cpp:186 (KJS::PropertyMap::markChildren):187 * kjs/property_map.h:188 * kjs/scope_chain.h:189 * kjs/string_object.cpp:190 (KJS::StringInstance::markChildren):191 * kjs/string_object.h:192 193 1 2007-11-27 Alp Toker <[email protected]> 194 2 -
trunk/JavaScriptCore/JavaScriptCore.exp
r28106 r28110 123 123 __ZN3KJS11Interpreter24setShouldPrintExceptionsEb 124 124 __ZN3KJS11Interpreter27resetGlobalObjectPropertiesEv 125 __ZN3KJS11Interpreter4markEv 125 126 __ZN3KJS11Interpreter6s_hookE 126 127 __ZN3KJS11Interpreter8evaluateERKNS_7UStringEiPKNS_5UCharEiPNS_7JSValueE 127 128 __ZN3KJS11Interpreter8evaluateERKNS_7UStringEiS3_PNS_7JSValueE 128 __ZN3KJS11Interpreter9markRootsERNS_9MarkStackE129 129 __ZN3KJS11InterpreterC1Ev 130 130 __ZN3KJS11InterpreterC2Ev … … 145 145 __ZN3KJS13SavedBuiltinsD1Ev 146 146 __ZN3KJS13jsOwnedStringERKNS_7UStringE 147 __ZN3KJS14StringInstance12markChildrenERNS_9MarkStackE148 147 __ZN3KJS14StringInstance14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE 149 148 __ZN3KJS14StringInstance16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE … … 154 153 __ZN3KJS14StringInstanceC1EPNS_8JSObjectERKNS_7UStringE 155 154 __ZN3KJS14StringInstanceC2EPNS_8JSObjectERKNS_7UStringE 155 __ZN3KJS15JSWrapperObject4markEv 156 156 __ZN3KJS15SavedPropertiesC1Ev 157 157 __ZN3KJS15SavedPropertiesD1Ev … … 202 202 __ZN3KJS8DebuggerD2Ev 203 203 __ZN3KJS8JSObject11hasInstanceEPNS_9ExecStateEPNS_7JSValueE 204 __ZN3KJS8JSObject12markChildrenERNS_9MarkStackE205 204 __ZN3KJS8JSObject12removeDirectERKNS_10IdentifierE 206 205 __ZN3KJS8JSObject14callAsFunctionEPNS_9ExecStateEPS0_RKNS_4ListE … … 214 213 __ZN3KJS8JSObject3putEPNS_9ExecStateEjPNS_7JSValueEi 215 214 __ZN3KJS8JSObject4callEPNS_9ExecStateEPS0_RKNS_4ListE 215 __ZN3KJS8JSObject4markEv 216 216 __ZN3KJS8JSObject9constructEPNS_9ExecStateERKNS_4ListE 217 217 __ZN3KJS8JSObject9constructEPNS_9ExecStateERKNS_4ListERKNS_10IdentifierERKNS_7UStringEi -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r28106 r28110 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, ); }; };103 102 65B1749A09D0FEB700820339 /* array_object.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B1749909D0FEB700820339 /* array_object.lut.h */; }; 104 103 65B174F509D100FA00820339 /* math_object.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B174F109D100FA00820339 /* math_object.lut.h */; }; … … 512 511 6592C316098B7DE10003D4F6 /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = "<group>"; }; 513 512 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>"; };515 513 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>"; }; 516 514 65B174BE09D1000200820339 /* chartables.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.c; fileEncoding = 30; path = chartables.c; sourceTree = "<group>"; }; … … 1011 1009 F692A8690255597D01FF60F7 /* lookup.h */, 1012 1010 F692A86A0255597D01FF60F7 /* math_object.cpp */, 1013 65A8B8D80CF408E900DC7C27 /* MarkStack.h */,1014 1011 F692A86B0255597D01FF60F7 /* math_object.h */, 1015 1012 F692A86D0255597D01FF60F7 /* nodes.cpp */, … … 1174 1171 65F340940CD6C1C000C0CA8B /* LocalStorage.h in Headers */, 1175 1172 5DBD18B00C5401A700C15EAE /* MallocZoneSupport.h in Headers */, 1176 65A8B8DB0CF408F400DC7C27 /* MarkStack.h in Headers */,1177 1173 BCF655590A2049710038A194 /* MathExtras.h in Headers */, 1178 1174 932F5B840822A1C700736975 /* NP_jsobject.h in Headers */, -
trunk/JavaScriptCore/kjs/ExecState.cpp
r28106 r28110 89 89 } 90 90 91 void ExecState::mark Children(MarkStack& stack)91 void ExecState::mark() 92 92 { 93 93 for (ExecState* exec = this; exec; exec = exec->m_callingExecState) 94 exec->m_scopeChain.mark Children(stack);94 exec->m_scopeChain.mark(); 95 95 } 96 96 -
trunk/JavaScriptCore/kjs/ExecState.h
r28106 r28110 101 101 void setGlobalObject(JSGlobalObject*); 102 102 103 void mark Children(MarkStack&);103 void mark(); 104 104 105 105 // This is a workaround to avoid accessing the global variables for these identifiers in -
trunk/JavaScriptCore/kjs/JSWrapperObject.cpp
r28106 r28110 25 25 namespace KJS { 26 26 27 void JSWrapperObject::mark Children(MarkStack& stack)27 void JSWrapperObject::mark() 28 28 { 29 JSObject::markChildren(stack); 30 stack.pushAtom(m_internalValue); 29 JSObject::mark(); 30 if (m_internalValue && !m_internalValue->marked()) 31 m_internalValue->mark(); 31 32 } 32 33 -
trunk/JavaScriptCore/kjs/JSWrapperObject.h
r28106 r28110 57 57 void setInternalValue(JSValue* v); 58 58 59 virtual void mark Children(MarkStack& stack);59 virtual void mark(); 60 60 61 61 private: … … 65 65 inline JSWrapperObject::JSWrapperObject(JSValue* proto) 66 66 : JSObject(proto) 67 , m_internalValue( jsNull())67 , m_internalValue(0) 68 68 { 69 69 } -
trunk/JavaScriptCore/kjs/array_instance.cpp
r28106 r28110 403 403 } 404 404 405 void ArrayInstance::mark Children(MarkStack& stack)406 { 407 JSObject::mark Children(stack);405 void ArrayInstance::mark() 406 { 407 JSObject::mark(); 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 )415 stack.push(value);414 if (value && !value->marked()) 415 value->mark(); 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 stack.push(it->second); 420 for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) { 421 JSValue* value = it->second; 422 if (!value->marked()) 423 value->mark(); 424 } 422 425 } 423 426 } -
trunk/JavaScriptCore/kjs/array_instance.h
r28106 r28110 43 43 virtual void getPropertyNames(ExecState*, PropertyNameArray&); 44 44 45 virtual void mark Children(MarkStack&);45 virtual void mark(); 46 46 47 47 virtual const ClassInfo* classInfo() const { return &info; } -
trunk/JavaScriptCore/kjs/bool_object.cpp
r28106 r28110 37 37 : JSWrapperObject(proto) 38 38 { 39 }40 41 void BooleanInstance::markChildren(MarkStack& stack)42 {43 JSObject::markChildren(stack);44 ASSERT(JSImmediate::isImmediate(internalValue()));45 39 } 46 40 -
trunk/JavaScriptCore/kjs/bool_object.h
r28106 r28110 33 33 34 34 virtual const ClassInfo *classInfo() const { return &info; } 35 virtual void markChildren(MarkStack& stack);36 35 static const ClassInfo info; 37 36 }; -
trunk/JavaScriptCore/kjs/collector.cpp
r28106 r28110 27 27 #include "internal.h" 28 28 #include "list.h" 29 #include "MarkStack.h"30 29 #include "value.h" 31 30 #include <algorithm> … … 279 278 targetBlock = (Block*)allocateBlock(); 280 279 targetBlock->freeList = targetBlock->cells; 281 if (heapType == PrimaryHeap)282 targetBlock->mayHaveRefs = 1;283 280 targetBlockUsedCells = 0; 284 281 heap.blocks[usedBlocks] = (CollectorBlock*)targetBlock; … … 483 480 #define IS_HALF_CELL_ALIGNED(p) (((intptr_t)(p) & (CELL_MASK >> 1)) == 0) 484 481 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) 482 void Collector::markStackObjectsConservatively(void *start, void *end) 493 483 { 494 484 if (start > end) { … … 532 522 if (((CollectorCell*)xAsBits)->u.freeCell.zeroIfFree != 0) { 533 523 JSCell* imp = reinterpret_cast<JSCell*>(xAsBits); 534 stack.push(imp);535 drainMarkStack(stack);524 if (!imp->marked()) 525 imp->mark(); 536 526 } 537 527 break; … … 544 534 } 545 535 546 void Collector::markCurrentThreadConservatively( MarkStack& stack)536 void Collector::markCurrentThreadConservatively() 547 537 { 548 538 // setjmp forces volatile registers onto the stack … … 561 551 void* stackBase = currentThreadStackBase(); 562 552 563 markStackObjectsConservatively(stack , stackPointer, stackBase);553 markStackObjectsConservatively(stackPointer, stackBase); 564 554 } 565 555 … … 704 694 } 705 695 706 void Collector::markOtherThreadConservatively( MarkStack& stack,Thread* thread)696 void Collector::markOtherThreadConservatively(Thread* thread) 707 697 { 708 698 suspendThread(thread->platformThread); … … 712 702 713 703 // mark the thread's registers 714 markStackObjectsConservatively( stack,(void*)®s, (void*)((char*)®s + regSize));704 markStackObjectsConservatively((void*)®s, (void*)((char*)®s + regSize)); 715 705 716 706 void* stackPointer = otherThreadStackPointer(regs); 717 707 void* stackBase = otherThreadStackBase(regs, thread); 718 markStackObjectsConservatively(stack , stackPointer, stackBase);708 markStackObjectsConservatively(stackPointer, stackBase); 719 709 720 710 resumeThread(thread->platformThread); … … 723 713 #endif 724 714 725 void Collector::markStackObjectsConservatively( MarkStack& stack)726 { 727 markCurrentThreadConservatively( stack);715 void Collector::markStackObjectsConservatively() 716 { 717 markCurrentThreadConservatively(); 728 718 729 719 #if USE(MULTIPLE_THREADS) 730 720 for (Thread *thread = registeredThreads; thread != NULL; thread = thread->next) { 731 721 if (!pthread_equal(thread->posixThread, pthread_self())) { 732 markOtherThreadConservatively(stack,thread);722 markOtherThreadConservatively(thread); 733 723 } 734 724 } … … 782 772 } 783 773 784 void Collector::markProtectedObjects( MarkStack& stack)774 void Collector::markProtectedObjects() 785 775 { 786 776 ProtectCountSet& protectedValues = KJS::protectedValues(); 787 777 ProtectCountSet::iterator end = protectedValues.end(); 788 778 for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it) { 789 stack.push(it->first); 790 drainMarkStack(stack); 791 } 792 } 793 794 void Collector::markMainThreadOnlyObjects(MarkStack& stack) 779 JSCell *val = it->first; 780 if (!val->marked()) 781 val->mark(); 782 } 783 } 784 785 void Collector::markMainThreadOnlyObjects() 795 786 { 796 787 #if USE(MULTIPLE_THREADS) … … 824 815 if (!curBlock->marked.get(i)) { 825 816 JSCell* imp = reinterpret_cast<JSCell*>(cell); 826 stack.push(imp); 827 drainMarkStack(stack); 817 imp->mark(); 828 818 } 829 819 if (++count == mainThreadOnlyObjectCount) … … 961 951 // MARK: first mark all referenced objects recursively starting out from the set of root objects 962 952 963 size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects;964 965 MarkStack stack;966 stack.reserveCapacity(primaryHeap.numLiveObjects);967 968 953 #ifndef NDEBUG 969 954 // Forbid malloc during the mark phase. Marking a thread suspends it, so 970 // a malloc inside mark Children() would risk a deadlock with a thread that had been955 // a malloc inside mark() would risk a deadlock with a thread that had been 971 956 // suspended while holding the malloc lock. 972 957 fastMallocForbid(); … … 976 961 Interpreter* scr = Interpreter::s_hook; 977 962 do { 978 scr->markRoots(stack); 979 drainMarkStack(stack); 963 scr->mark(); 980 964 scr = scr->next; 981 965 } while (scr != Interpreter::s_hook); 982 966 } 983 967 984 markStackObjectsConservatively(stack); 985 markProtectedObjects(stack); 986 List::markProtectedLists(stack); 987 drainMarkStack(stack); 968 markStackObjectsConservatively(); 969 markProtectedObjects(); 970 List::markProtectedLists(); 988 971 #if USE(MULTIPLE_THREADS) 989 972 if (!currentThreadIsMainThread) 990 markMainThreadOnlyObjects( stack);973 markMainThreadOnlyObjects(); 991 974 #endif 992 975 … … 995 978 #endif 996 979 980 size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects; 997 981 size_t numLiveObjects = sweep<PrimaryHeap>(currentThreadIsMainThread); 998 982 numLiveObjects += sweep<NumberHeap>(currentThreadIsMainThread); -
trunk/JavaScriptCore/kjs/collector.h
r28106 r28110 32 32 namespace KJS { 33 33 34 class CollectorBlock;35 34 class JSCell; 36 35 class JSValue; 37 class MarkStack;36 class CollectorBlock; 38 37 39 38 class Collector { … … 67 66 static bool isCellMarked(const JSCell*); 68 67 static void markCell(JSCell*); 69 static bool cellMayHaveRefs(const JSCell*);70 68 71 69 enum HeapType { PrimaryHeap, NumberHeap }; … … 81 79 82 80 static void recordExtraCost(size_t); 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);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); 89 87 90 88 static size_t mainThreadOnlyObjectCount; … … 110 108 const size_t CELL_MASK = CELL_SIZE - 1; 111 109 const size_t CELL_ALIGN_MASK = ~CELL_MASK; 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);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); 113 111 const size_t SMALL_CELLS_PER_BLOCK = 2 * CELLS_PER_BLOCK; 114 112 const size_t BITMAP_SIZE = (CELLS_PER_BLOCK + 7) / 8; … … 148 146 uint32_t usedCells; 149 147 CollectorCell* freeList; 150 uint32_t mayHaveRefs;151 148 CollectorBitmap marked; 152 149 CollectorBitmap collectOnMainThreadOnly; … … 158 155 uint32_t usedCells; 159 156 SmallCollectorCell* freeList; 160 uint32_t mayHaveRefs;161 157 CollectorBitmap marked; 162 158 CollectorBitmap collectOnMainThreadOnly; … … 188 184 } 189 185 190 inline bool Collector::cellMayHaveRefs(const JSCell* cell)191 {192 return cellBlock(cell)->mayHaveRefs;193 }194 195 186 inline void Collector::reportExtraMemoryCost(size_t cost) 196 187 { -
trunk/JavaScriptCore/kjs/error_object.cpp
r28106 r28110 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
r28106 r28110 76 76 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); 77 77 78 virtual void mark(); 79 78 80 virtual const ClassInfo *classInfo() const { return &info; } 79 81 static const ClassInfo info; -
trunk/JavaScriptCore/kjs/function.cpp
r28106 r28110 62 62 } 63 63 64 void FunctionImp::mark Children(MarkStack& stack)65 { 66 InternalFunctionImp::mark Children(stack);67 _scope.mark Children(stack);64 void FunctionImp::mark() 65 { 66 InternalFunctionImp::mark(); 67 _scope.mark(); 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::markChildren(MarkStack& stack) 351 { 352 JSObject::markChildren(stack); 353 stack.push(_activationObject); 350 void Arguments::mark() 351 { 352 JSObject::mark(); 353 if (_activationObject && !_activationObject->marked()) 354 _activationObject->mark(); 354 355 } 355 356 … … 484 485 } 485 486 486 void ActivationImp::mark Children(MarkStack& stack)487 { 488 JSObject::mark Children(stack);487 void ActivationImp::mark() 488 { 489 JSObject::mark(); 489 490 490 491 size_t size = d->localStorage.size(); 491 for (size_t i = 0; i < size; ++i) 492 stack.push(d->localStorage[i].value); 492 for (size_t i = 0; i < size; ++i) { 493 JSValue* value = d->localStorage[i].value; 494 if (!value->marked()) 495 value->mark(); 496 } 493 497 494 stack.push(d->function); 495 if (d->argumentsObject) 496 stack.push(d->argumentsObject); 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(); 497 504 } 498 505 -
trunk/JavaScriptCore/kjs/function.h
r28106 r28110 96 96 const ScopeChain& scope() const { return _scope; } 97 97 98 virtual void mark Children(MarkStack&);98 virtual void mark(); 99 99 100 100 private: … … 125 125 public: 126 126 Arguments(ExecState*, FunctionImp* func, const List& args, ActivationImp* act); 127 virtual void mark Children(MarkStack&);127 virtual void mark(); 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 Children(MarkStack&);167 virtual void mark(); 168 168 169 169 bool isActivation() { return true; } -
trunk/JavaScriptCore/kjs/internal.cpp
r28106 r28110 145 145 146 146 // --------------------------- GetterSetterImp --------------------------------- 147 void GetterSetterImp::markChildren(MarkStack& stack) 148 { 149 if (getter) 150 stack.push(getter); 151 if (setter) 152 stack.push(setter); 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(); 153 155 } 154 156 -
trunk/JavaScriptCore/kjs/interpreter.cpp
r28106 r28110 545 545 } 546 546 547 void Interpreter::mark Roots(MarkStack& stack)547 void Interpreter::mark() 548 548 { 549 549 if (m_currentExec) 550 m_currentExec->mark Children(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);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(); 621 621 } 622 622 -
trunk/JavaScriptCore/kjs/interpreter.h
r28106 r28110 291 291 * implementing custom mark methods must make sure to chain to this one. 292 292 */ 293 virtual void mark Roots(MarkStack&);293 virtual void mark(); 294 294 295 295 static bool shouldPrintExceptions(); -
trunk/JavaScriptCore/kjs/list.cpp
r28106 r28110 44 44 } 45 45 46 void List::markProtectedListsSlowCase( MarkStack& stack)46 void List::markProtectedListsSlowCase() 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 stack.push(*it2); 53 for (iterator it2 = list->begin(); it2 != end2; ++it2) { 54 JSValue* v = *it2; 55 if (!v->marked()) 56 v->mark(); 57 } 55 58 } 56 59 } -
trunk/JavaScriptCore/kjs/list.h
r28106 r28110 86 86 const_iterator end() const { return m_vector.end(); } 87 87 88 static void markProtectedLists( MarkStack& stack)88 static void markProtectedLists() 89 89 { 90 90 if (!markSet().size()) 91 91 return; 92 markProtectedListsSlowCase( stack);92 markProtectedListsSlowCase(); 93 93 } 94 94 … … 97 97 private: 98 98 static ListSet& markSet(); 99 static void markProtectedListsSlowCase( MarkStack&);99 static void markProtectedListsSlowCase(); 100 100 101 101 void expandAndAppend(JSValue*); -
trunk/JavaScriptCore/kjs/object.cpp
r28106 r28110 114 114 // ------------------------------ JSObject ------------------------------------ 115 115 116 void JSObject::markChildren(MarkStack& stack) 117 { 116 void JSObject::mark() 117 { 118 JSCell::mark(); 119 118 120 #if JAVASCRIPT_MARK_TRACING 119 121 static int markStackDepth = 0; … … 125 127 #endif 126 128 127 stack.push(_proto); 128 _prop.markChildren(stack); 129 JSValue *proto = _proto; 130 if (!proto->marked()) 131 proto->mark(); 132 133 _prop.mark(); 129 134 130 135 #if JAVASCRIPT_MARK_TRACING -
trunk/JavaScriptCore/kjs/object.h
r28106 r28110 28 28 #include "JSType.h" 29 29 #include "CommonIdentifiers.h" 30 #include "MarkStack.h"31 30 #include "interpreter.h" 32 31 #include "property_map.h" … … 86 85 virtual JSObject *toObject(ExecState *exec) const; 87 86 88 virtual void mark Children(MarkStack&);87 virtual void mark(); 89 88 90 89 JSObject *getGetter() { return getter; } … … 113 112 JSObject(); 114 113 115 virtual void mark Children(MarkStack&);114 virtual void mark(); 116 115 virtual JSType type() const; 117 116 … … 588 587 // 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. 589 588 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); 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(); 595 595 } 596 596 } -
trunk/JavaScriptCore/kjs/property_map.cpp
r28106 r28110 623 623 } 624 624 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); 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 } 631 634 #endif 632 635 return; … … 634 637 635 638 unsigned entryCount = m_u.table->keyCount + m_u.table->deletedSentinelCount; 636 for (unsigned i = 1; i <= entryCount; i++) 637 stack.push(m_u.table->entries()[i].value); 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 } 638 644 } 639 645 -
trunk/JavaScriptCore/kjs/property_map.h
r28106 r28110 30 30 class JSObject; 31 31 class JSValue; 32 class MarkStack;33 32 class PropertyNameArray; 34 33 … … 61 60 JSValue** getLocation(const Identifier& name); 62 61 63 void mark Children(MarkStack&) const;62 void mark() const; 64 63 void getEnumerablePropertyNames(PropertyNameArray&) const; 65 64 -
trunk/JavaScriptCore/kjs/scope_chain.h
r28106 r28110 83 83 void pop(); 84 84 85 void mark Children(MarkStack&);85 void mark(); 86 86 87 87 #ifndef NDEBUG -
trunk/JavaScriptCore/kjs/string_object.cpp
r28106 r28110 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());136 130 } 137 131 -
trunk/JavaScriptCore/kjs/string_object.h
r28106 r28110 47 47 48 48 StringImp* internalValue() const { return static_cast<StringImp*>(JSWrapperObject::internalValue());} 49 virtual void markChildren(MarkStack& stack);50 49 51 50 private: -
trunk/JavaScriptCore/kjs/value.h
r28106 r28110 34 34 class JSObject; 35 35 class JSCell; 36 class MarkStack;37 36 38 37 struct ClassInfo; … … 49 48 friend class JSCell; // so it can derive from this class 50 49 friend class Collector; // so it can call asCell() 51 friend class MarkStack; // so it can call asCell()52 50 53 51 private: … … 108 106 109 107 // Garbage collection. 110 void mark Children(MarkStack&);108 void mark(); 111 109 bool marked() const; 112 110 … … 167 165 // Garbage collection. 168 166 void *operator new(size_t); 169 virtual void mark Children(MarkStack&);167 virtual void mark(); 170 168 bool marked() const; 171 169 }; … … 293 291 } 294 292 295 inline void JSCell::markChildren(MarkStack&) 296 { 293 inline void JSCell::mark() 294 { 295 return Collector::markCell(this); 297 296 } 298 297 … … 408 407 } 409 408 410 inline void JSValue::mark Children(MarkStack& stack)411 { 412 ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling mark Children()413 asCell()->mark Children(stack);409 inline void JSValue::mark() 410 { 411 ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling mark() 412 asCell()->mark(); 414 413 } 415 414
Note:
See TracChangeset
for help on using the changeset viewer.