Changeset 110127 in webkit
- Timestamp:
- Mar 7, 2012 6:14:38 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r110122 r110127 1 2012-03-07 Mark Hahnenberg <mhahnenberg@apple.com> 2 3 Refactor recompileAllJSFunctions() to be less expensive 4 https://bugs.webkit.org/show_bug.cgi?id=80330 5 6 Reviewed by Geoffrey Garen. 7 8 This change is performance neutral on the JS benchmarks we track. It's mostly to improve page 9 load performance, which currently does at least a couple full GCs per navigation. 10 11 * heap/Heap.cpp: 12 (JSC::Heap::discardAllCompiledCode): Rename recompileAllJSFunctions to discardAllCompiledCode 13 because the function doesn't actually recompile anything (and never did); it simply throws code 14 away for it to be recompiled later if we determine we should do so. 15 (JSC): 16 (JSC::Heap::collectAllGarbage): 17 (JSC::Heap::addFunctionExecutable): Adds a newly created FunctionExecutable to the Heap's list. 18 (JSC::Heap::removeFunctionExecutable): Removes the specified FunctionExecutable from the Heap's list. 19 * heap/Heap.h: 20 (JSC): 21 (Heap): 22 * runtime/Executable.cpp: Added next and prev fields to FunctionExecutables so that they can 23 be used in DoublyLinkedLists. 24 (JSC::FunctionExecutable::FunctionExecutable): 25 (JSC::FunctionExecutable::finalize): Removes the FunctionExecutable from the Heap's list. 26 * runtime/Executable.h: 27 (FunctionExecutable): 28 (JSC::FunctionExecutable::create): Adds the FunctionExecutable to the Heap's list. 29 * runtime/JSGlobalData.cpp: Remove recompileAllJSFunctions, as it's the Heap's job to own and manage 30 the list of FunctionExecutables. 31 * runtime/JSGlobalData.h: 32 (JSGlobalData): 33 * runtime/JSGlobalObject.cpp: 34 (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): Use the new discardAllCompiledCode. 35 1 36 2012-03-06 Oliver Hunt <oliver@apple.com> 2 37 -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r109956 r110127 765 765 } 766 766 767 void Heap::discardAllCompiledCode() 768 { 769 // If JavaScript is running, it's not safe to recompile, since we'll end 770 // up throwing away code that is live on the stack. 771 ASSERT(!m_globalData->dynamicGlobalObject); 772 773 for (FunctionExecutable* current = m_functions.head(); current; current = current->next()) 774 current->discardCode(); 775 } 776 767 777 void Heap::collectAllGarbage() 768 778 { … … 770 780 return; 771 781 if (!m_globalData->dynamicGlobalObject) 772 m_globalData->recompileAllJSFunctions();782 discardAllCompiledCode(); 773 783 774 784 collect(DoSweep); … … 925 935 } 926 936 937 void Heap::addFunctionExecutable(FunctionExecutable* executable) 938 { 939 m_functions.append(executable); 940 } 941 942 void Heap::removeFunctionExecutable(FunctionExecutable* executable) 943 { 944 m_functions.remove(executable); 945 } 946 927 947 } // namespace JSC -
trunk/Source/JavaScriptCore/heap/Heap.h
r109956 r110127 43 43 class CopiedSpace; 44 44 class CodeBlock; 45 class FunctionExecutable; 45 46 class GCActivityCallback; 46 47 class GlobalCodeBlock; … … 106 107 typedef void (*Finalizer)(JSCell*); 107 108 JS_EXPORT_PRIVATE void addFinalizer(JSCell*, Finalizer); 109 void addFunctionExecutable(FunctionExecutable*); 110 void removeFunctionExecutable(FunctionExecutable*); 108 111 109 112 void notifyIsSafeToCollect() { m_isSafeToCollect = true; } … … 140 143 141 144 double lastGCLength() { return m_lastGCLength; } 145 146 void discardAllCompiledCode(); 142 147 143 148 private: … … 240 245 JSGlobalData* m_globalData; 241 246 double m_lastGCLength; 247 248 DoublyLinkedList<FunctionExecutable> m_functions; 242 249 }; 243 250 -
trunk/Source/JavaScriptCore/runtime/Executable.cpp
r110033 r110127 147 147 , m_inferredName(inferredName.isNull() ? globalData.propertyNames->emptyIdentifier : inferredName) 148 148 , m_symbolTable(0) 149 , m_next(0) 150 , m_prev(0) 149 151 { 150 152 } … … 158 160 , m_inferredName(inferredName.isNull() ? exec->globalData().propertyNames->emptyIdentifier : inferredName) 159 161 , m_symbolTable(0) 162 , m_next(0) 163 , m_prev(0) 160 164 { 161 165 } … … 655 659 void FunctionExecutable::finalize(JSCell* cell) 656 660 { 657 jsCast<FunctionExecutable*>(cell)->clearCode(); 661 FunctionExecutable* executable = jsCast<FunctionExecutable*>(cell); 662 Heap::heap(executable)->removeFunctionExecutable(executable); 663 executable->clearCode(); 658 664 } 659 665 -
trunk/Source/JavaScriptCore/runtime/Executable.h
r109863 r110127 464 464 }; 465 465 466 class FunctionExecutable : public ScriptExecutable {466 class FunctionExecutable : public ScriptExecutable, public DoublyLinkedListNode<FunctionExecutable> { 467 467 friend class JIT; 468 468 friend class LLIntOffsetsExtractor; 469 friend class DoublyLinkedListNode<FunctionExecutable>; 469 470 public: 470 471 typedef ScriptExecutable Base; … … 474 475 FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(*exec->heap())) FunctionExecutable(exec, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext); 475 476 executable->finishCreation(exec->globalData(), name, firstLine, lastLine); 477 exec->globalData().heap.addFunctionExecutable(executable); 476 478 exec->globalData().heap.addFinalizer(executable, &finalize); 477 479 return executable; … … 482 484 FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext); 483 485 executable->finishCreation(globalData, name, firstLine, lastLine); 486 globalData.heap.addFunctionExecutable(executable); 484 487 globalData.heap.addFinalizer(executable, &finalize); 485 488 return executable; … … 689 692 WriteBarrier<JSString> m_nameValue; 690 693 SharedSymbolTable* m_symbolTable; 694 FunctionExecutable* m_next; 695 FunctionExecutable* m_prev; 691 696 }; 692 697 -
trunk/Source/JavaScriptCore/runtime/JSGlobalData.cpp
r109863 r110127 69 69 using namespace WTF; 70 70 71 namespace {72 73 using namespace JSC;74 75 class Recompiler : public MarkedBlock::VoidFunctor {76 public:77 void operator()(JSCell*);78 };79 80 inline void Recompiler::operator()(JSCell* cell)81 {82 if (!cell->inherits(&JSFunction::s_info))83 return;84 JSFunction* function = asFunction(cell);85 if (!function->executable() || function->executable()->isHostFunction())86 return;87 function->jsExecutable()->discardCode();88 }89 90 } // namespace91 92 71 namespace JSC { 93 72 … … 444 423 } 445 424 446 void JSGlobalData::recompileAllJSFunctions()447 {448 // If JavaScript is running, it's not safe to recompile, since we'll end449 // up throwing away code that is live on the stack.450 ASSERT(!dynamicGlobalObject);451 452 heap.objectSpace().forEachCell<Recompiler>();453 }454 455 425 struct StackPreservingRecompiler : public MarkedBlock::VoidFunctor { 456 426 HashSet<FunctionExecutable*> currentlyExecutingFunctions; -
trunk/Source/JavaScriptCore/runtime/JSGlobalData.h
r109863 r110127 325 325 JS_EXPORT_PRIVATE void stopSampling(); 326 326 JS_EXPORT_PRIVATE void dumpSampleData(ExecState* exec); 327 void recompileAllJSFunctions();327 void discardAllCompiledCode(); 328 328 RegExpCache* regExpCache() { return m_regExpCache; } 329 329 #if ENABLE(REGEXP_TRACING) -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r108259 r110127 461 461 #if ENABLE(ASSEMBLER) 462 462 if (ExecutableAllocator::underMemoryPressure()) 463 globalData. recompileAllJSFunctions();463 globalData.heap.discardAllCompiledCode(); 464 464 #endif 465 465
Note: See TracChangeset
for help on using the changeset viewer.