Changeset 181887 in webkit
- Timestamp:
- Mar 23, 2015, 10:37:19 PM (11 years ago)
- Location:
- trunk/Source
- Files:
-
- 15 edited
-
JavaScriptCore/ChangeLog (modified) (1 diff)
-
JavaScriptCore/assembler/LinkBuffer.cpp (modified) (2 diffs)
-
JavaScriptCore/assembler/LinkBuffer.h (modified) (5 diffs)
-
JavaScriptCore/dfg/DFGJITCompiler.cpp (modified) (1 diff)
-
JavaScriptCore/dfg/DFGJITFinalizer.cpp (modified) (4 diffs)
-
JavaScriptCore/disassembler/Disassembler.cpp (modified) (3 diffs)
-
JavaScriptCore/disassembler/Disassembler.h (modified) (3 diffs)
-
JavaScriptCore/ftl/FTLCompile.cpp (modified) (2 diffs)
-
JavaScriptCore/ftl/FTLLink.cpp (modified) (1 diff)
-
JavaScriptCore/jit/JIT.cpp (modified) (4 diffs)
-
JavaScriptCore/jsc.cpp (modified) (2 diffs)
-
JavaScriptCore/runtime/Options.h (modified) (1 diff)
-
JavaScriptCore/runtime/VM.cpp (modified) (2 diffs)
-
WTF/ChangeLog (modified) (1 diff)
-
WTF/wtf/StringPrintStream.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r181871 r181887 1 2015-03-23 Filip Pizlo <fpizlo@apple.com> 2 3 JSC should have a low-cost asynchronous disassembler 4 https://bugs.webkit.org/show_bug.cgi?id=142997 5 6 Reviewed by Mark Lam. 7 8 This adds a JSC_asyncDisassembly option that disassembles on a thread. Disassembly 9 doesn't block execution. Some code will live a little longer because of this, since the 10 work tasks hold a ref to the code, but other than that there is basically no overhead. 11 12 At present, this isn't really a replacement for JSC_showDisassembly, since it doesn't 13 provide contextual IR information for Baseline and DFG disassemblies, and it doesn't do 14 the separate IR dumps for FTL. Using JSC_showDisassembly and friends along with 15 JSC_asyncDisassembly has bizarre behavior - so just choose one. 16 17 A simple way of understanding how great this is, is to run a small benchmark like 18 V8Spider/earley-boyer. 19 20 Performance without any disassembly flags: 60ms 21 Performance with JSC_showDisassembly=true: 477ms 22 Performance with JSC_asyncDisassembly=true: 65ms 23 24 So, the overhead of disassembly goes from 8x to 8%. 25 26 Note that JSC_asyncDisassembly=true does make it incorrect to run "time" as a way of 27 measuring benchmark performance. This is because at VM exit, we wait for all async 28 disassembly requests to finish. For example, for earley-boyer, we spend an extra ~130ms 29 after the benchmark completely finishes to finish the disassemblies. This small weirdness 30 should be OK for the intended use-cases, since all you have to do to get around it is to 31 measure the execution time of the benchmark payload rather than the end-to-end time of 32 launching the VM. 33 34 * assembler/LinkBuffer.cpp: 35 (JSC::LinkBuffer::finalizeCodeWithDisassembly): 36 * assembler/LinkBuffer.h: 37 (JSC::LinkBuffer::wasAlreadyDisassembled): 38 (JSC::LinkBuffer::didAlreadyDisassemble): 39 * dfg/DFGJITCompiler.cpp: 40 (JSC::DFG::JITCompiler::disassemble): 41 * dfg/DFGJITFinalizer.cpp: 42 (JSC::DFG::JITFinalizer::finalize): 43 (JSC::DFG::JITFinalizer::finalizeFunction): 44 * disassembler/Disassembler.cpp: 45 (JSC::disassembleAsynchronously): 46 (JSC::waitForAsynchronousDisassembly): 47 * disassembler/Disassembler.h: 48 * ftl/FTLCompile.cpp: 49 (JSC::FTL::mmAllocateDataSection): 50 * ftl/FTLLink.cpp: 51 (JSC::FTL::link): 52 * jit/JIT.cpp: 53 (JSC::JIT::privateCompile): 54 * jsc.cpp: 55 * runtime/Options.h: 56 * runtime/VM.cpp: 57 (JSC::VM::~VM): 58 1 59 2015-03-23 Dean Jackson <dino@apple.com> 2 60 -
trunk/Source/JavaScriptCore/assembler/LinkBuffer.cpp
r171123 r181887 1 1 /* 2 * Copyright (C) 2012 , 2013, 2014Apple Inc. All rights reserved.2 * Copyright (C) 2012-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 60 60 CodeRef result = finalizeCodeWithoutDisassembly(); 61 61 62 #if ENABLE(DISASSEMBLER) 63 dataLogF("Generated JIT code for "); 62 if (m_alreadyDisassembled) 63 return result; 64 65 StringPrintStream out; 66 out.printf("Generated JIT code for "); 64 67 va_list argList; 65 68 va_start(argList, format); 66 WTF::dataLogFV(format, argList);69 out.vprintf(format, argList); 67 70 va_end(argList); 68 dataLogF(":\n"); 69 70 dataLogF(" Code at [%p, %p):\n", result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size()); 71 out.printf(":\n"); 72 73 out.printf(" Code at [%p, %p):\n", result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size()); 74 75 CString header = out.toCString(); 76 77 if (Options::asyncDisassembly()) { 78 disassembleAsynchronously(header, result, m_size, " "); 79 return result; 80 } 81 82 dataLog(header); 71 83 disassemble(result.code(), m_size, " ", WTF::dataFile()); 72 #else73 UNUSED_PARAM(format);74 #endif // ENABLE(DISASSEMBLER)75 84 76 85 return result; -
trunk/Source/JavaScriptCore/assembler/LinkBuffer.h
r171123 r181887 1 1 /* 2 * Copyright (C) 2009, 2010, 2012 , 2013, 2014Apple Inc. All rights reserved.2 * Copyright (C) 2009, 2010, 2012-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 255 255 return m_size; 256 256 } 257 258 bool wasAlreadyDisassembled() const { return m_alreadyDisassembled; } 259 void didAlreadyDisassemble() { m_alreadyDisassembled = true; } 257 260 258 261 private: … … 311 314 bool m_completed; 312 315 #endif 316 bool m_alreadyDisassembled { false }; 313 317 }; 314 318 … … 321 325 322 326 #define FINALIZE_CODE_FOR(codeBlock, linkBufferReference, dataLogFArgumentsForHeading) \ 323 FINALIZE_CODE_IF(shouldShowDisassemblyFor(codeBlock) , linkBufferReference, dataLogFArgumentsForHeading)327 FINALIZE_CODE_IF(shouldShowDisassemblyFor(codeBlock) || Options::asyncDisassembly(), linkBufferReference, dataLogFArgumentsForHeading) 324 328 325 329 // Use this to finalize code, like so: … … 340 344 341 345 #define FINALIZE_CODE(linkBufferReference, dataLogFArgumentsForHeading) \ 342 FINALIZE_CODE_IF(JSC::Options:: showDisassembly(), linkBufferReference, dataLogFArgumentsForHeading)346 FINALIZE_CODE_IF(JSC::Options::asyncDisassembly() || JSC::Options::showDisassembly(), linkBufferReference, dataLogFArgumentsForHeading) 343 347 344 348 #define FINALIZE_DFG_CODE(linkBufferReference, dataLogFArgumentsForHeading) \ 345 FINALIZE_CODE_IF( (JSC::Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, dataLogFArgumentsForHeading)349 FINALIZE_CODE_IF(JSC::Options::asyncDisassembly() || JSC::Options::showDisassembly() || Options::showDFGDisassembly(), linkBufferReference, dataLogFArgumentsForHeading) 346 350 347 351 } // namespace JSC -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
r180423 r181887 455 455 void JITCompiler::disassemble(LinkBuffer& linkBuffer) 456 456 { 457 if (shouldShowDisassembly()) 457 if (shouldShowDisassembly()) { 458 458 m_disassembler->dump(linkBuffer); 459 linkBuffer.didAlreadyDisassemble(); 460 } 459 461 460 462 if (m_graph.m_plan.compilation) -
trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp
r176533 r181887 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 30 30 31 31 #include "CodeBlock.h" 32 #include "CodeBlockWithJITType.h" 32 33 #include "DFGCommon.h" 33 34 #include "DFGPlan.h" … … 57 58 { 58 59 m_jitCode->initializeCodeRef( 59 m_linkBuffer->finalizeCodeWithoutDisassembly(), MacroAssemblerCodePtr()); 60 FINALIZE_DFG_CODE(*m_linkBuffer, ("DFG JIT code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::DFGJIT)).data())), 61 MacroAssemblerCodePtr()); 62 60 63 m_plan.codeBlock->setJITCode(m_jitCode); 61 64 … … 69 72 RELEASE_ASSERT(!m_withArityCheck.isEmptyValue()); 70 73 m_jitCode->initializeCodeRef( 71 m_linkBuffer->finalizeCodeWithoutDisassembly(), m_withArityCheck); 74 FINALIZE_DFG_CODE(*m_linkBuffer, ("DFG JIT code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::DFGJIT)).data())), 75 m_withArityCheck); 72 76 m_plan.codeBlock->setJITCode(m_jitCode); 73 77 -
trunk/Source/JavaScriptCore/disassembler/Disassembler.cpp
r163760 r181887 1 1 /* 2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "MacroAssemblerCodeRef.h" 30 30 #include <wtf/DataLog.h> 31 #include <wtf/Deque.h> 32 #include <wtf/NeverDestroyed.h> 33 #include <wtf/StringPrintStream.h> 34 #include <wtf/Threading.h> 35 #include <wtf/ThreadingPrimitives.h> 31 36 32 37 namespace JSC { … … 40 45 } 41 46 47 namespace { 48 49 // This is really a struct, except that it should be a class because that's what the WTF_* macros 50 // expect. 51 class DisassemblyTask { 52 WTF_MAKE_NONCOPYABLE(DisassemblyTask); 53 WTF_MAKE_FAST_ALLOCATED; 54 public: 55 DisassemblyTask() 56 { 57 } 58 59 ~DisassemblyTask() 60 { 61 if (header) 62 free(header); // free() because it would have been copied by strdup. 63 } 64 65 char* header { nullptr }; 66 MacroAssemblerCodeRef codeRef; 67 size_t size { 0 }; 68 const char* prefix { nullptr }; 69 InstructionSubsetHint subsetHint { MacroAssemblerSubset }; 70 }; 71 72 class AsynchronousDisassembler { 73 public: 74 AsynchronousDisassembler() 75 { 76 createThread("Asynchronous Disassembler", [&] () { run(); }); 77 } 78 79 void enqueue(std::unique_ptr<DisassemblyTask> task) 80 { 81 MutexLocker locker(m_lock); 82 m_queue.append(WTF::move(task)); 83 m_condition.broadcast(); 84 } 85 86 void waitUntilEmpty() 87 { 88 MutexLocker locker(m_lock); 89 while (!m_queue.isEmpty() || m_working) 90 m_condition.wait(m_lock); 91 } 92 93 private: 94 NO_RETURN void run() 95 { 96 for (;;) { 97 std::unique_ptr<DisassemblyTask> task; 98 { 99 MutexLocker locker(m_lock); 100 m_working = false; 101 m_condition.broadcast(); 102 while (m_queue.isEmpty()) 103 m_condition.wait(m_lock); 104 task = m_queue.takeFirst(); 105 m_working = true; 106 } 107 108 dataLog(task->header); 109 disassemble( 110 task->codeRef.code(), task->size, task->prefix, WTF::dataFile(), 111 task->subsetHint); 112 } 113 } 114 115 Mutex m_lock; 116 ThreadCondition m_condition; 117 Deque<std::unique_ptr<DisassemblyTask>> m_queue; 118 bool m_working { false }; 119 }; 120 121 bool hadAnyAsynchronousDisassembly = false; 122 123 AsynchronousDisassembler& asynchronousDisassembler() 124 { 125 static NeverDestroyed<AsynchronousDisassembler> disassembler; 126 hadAnyAsynchronousDisassembly = true; 127 return disassembler.get(); 128 } 129 130 } // anonymous namespace 131 132 void disassembleAsynchronously( 133 const CString& header, const MacroAssemblerCodeRef& codeRef, size_t size, const char* prefix, 134 InstructionSubsetHint subsetHint) 135 { 136 std::unique_ptr<DisassemblyTask> task = std::make_unique<DisassemblyTask>(); 137 task->header = strdup(header.data()); // Yuck! We need this because CString does racy refcounting. 138 task->codeRef = codeRef; 139 task->size = size; 140 task->prefix = prefix; 141 task->subsetHint = subsetHint; 142 143 asynchronousDisassembler().enqueue(WTF::move(task)); 144 } 145 146 void waitForAsynchronousDisassembly() 147 { 148 if (!hadAnyAsynchronousDisassembly) 149 return; 150 151 asynchronousDisassembler().waitUntilEmpty(); 152 } 153 42 154 } // namespace JSC 43 155 -
trunk/Source/JavaScriptCore/disassembler/Disassembler.h
r164424 r181887 1 1 /* 2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #define Disassembler_h 28 28 29 #include <functional> 29 30 #include <wtf/PrintStream.h> 31 #include <wtf/text/CString.h> 30 32 31 33 namespace JSC { 32 34 33 35 class MacroAssemblerCodePtr; 36 class MacroAssemblerCodeRef; 34 37 35 38 enum InstructionSubsetHint { MacroAssemblerSubset, LLVMSubset }; … … 48 51 void disassemble(const MacroAssemblerCodePtr&, size_t, const char* prefix, PrintStream& out, InstructionSubsetHint = MacroAssemblerSubset); 49 52 53 // Asynchronous disassembly. This happens on another thread, and calls the provided 54 // callback when the disassembly is done. 55 void disassembleAsynchronously( 56 const CString& header, const MacroAssemblerCodeRef&, size_t, const char* prefix, 57 InstructionSubsetHint = MacroAssemblerSubset); 58 59 JS_EXPORT_PRIVATE void waitForAsynchronousDisassembly(); 60 50 61 } // namespace JSC 51 62 -
trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp
r180903 r181887 804 804 recordMap, didSeeUnwindInfo); 805 805 806 if (shouldShowDisassembly() ) {806 if (shouldShowDisassembly() || Options::asyncDisassembly()) { 807 807 for (unsigned i = 0; i < state.jitCode->handles().size(); ++i) { 808 808 if (state.codeSectionNames[i] != SECTION_NAME("text")) … … 810 810 811 811 ExecutableMemoryHandle* handle = state.jitCode->handles()[i].get(); 812 dataLog( 812 813 CString header = toCString( 813 814 "Generated LLVM code after stackmap-based fix-up for ", 814 815 CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), 815 816 " in ", state.graph.m_plan.mode, " #", i, ", ", 816 817 state.codeSectionNames[i], ":\n"); 818 819 if (Options::asyncDisassembly()) { 820 disassembleAsynchronously( 821 header, MacroAssemblerCodeRef(handle), handle->sizeInBytes(), " ", 822 LLVMSubset); 823 continue; 824 } 825 826 dataLog(header); 817 827 disassemble( 818 828 MacroAssemblerCodePtr(handle->start()), handle->sizeInBytes(), -
trunk/Source/JavaScriptCore/ftl/FTLLink.cpp
r176572 r181887 132 132 continue; 133 133 134 ExecutableMemoryHandle* handle = state.jitCode->handles()[i].get();135 disassemble(136 MacroAssemblerCodePtr(handle->start()), handle->sizeInBytes(),137 " ", out, LLVMSubset);134 ExecutableMemoryHandle* handle = state.jitCode->handles()[i].get(); 135 disassemble( 136 MacroAssemblerCodePtr(handle->start()), handle->sizeInBytes(), 137 " ", out, LLVMSubset); 138 138 } 139 139 compilation->addDescription(Profiler::OriginStack(), out.toCString()); -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r181466 r181887 1 1 /* 2 * Copyright (C) 2008, 2009, 2012 , 2013, 2014Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2009, 2012-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 #include "ArityCheckFailReturnThunks.h" 33 33 #include "CodeBlock.h" 34 #include "CodeBlockWithJITType.h" 34 35 #include "DFGCapabilities.h" 35 36 #include "Interpreter.h" … … 683 684 withArityCheck = patchBuffer.locationOf(arityCheck); 684 685 685 if (Options::showDisassembly()) 686 if (Options::showDisassembly()) { 686 687 m_disassembler->dump(patchBuffer); 688 patchBuffer.didAlreadyDisassemble(); 689 } 687 690 if (m_compilation) { 688 691 m_disassembler->reportToProfiler(m_compilation.get(), patchBuffer); … … 690 693 } 691 694 692 CodeRef result = patchBuffer.finalizeCodeWithoutDisassembly(); 695 CodeRef result = FINALIZE_CODE( 696 patchBuffer, 697 ("Baseline JIT code for %s", toCString(CodeBlockWithJITType(m_codeBlock, JITCode::BaselineJIT)).data())); 693 698 694 699 m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT.add( -
trunk/Source/JavaScriptCore/jsc.cpp
r181326 r181887 29 29 #include "Completion.h" 30 30 #include "CopiedSpaceInlines.h" 31 #include "Disassembler.h" 31 32 #include "ExceptionHelpers.h" 32 33 #include "HeapStatistics.h" … … 105 106 NO_RETURN_WITH_VALUE static void jscExit(int status) 106 107 { 108 waitForAsynchronousDisassembly(); 109 107 110 #if ENABLE(DFG_JIT) 108 111 if (DFG::isCrashing()) { -
trunk/Source/JavaScriptCore/runtime/Options.h
r180423 r181887 117 117 /* showDisassembly implies showDFGDisassembly. */ \ 118 118 v(bool, showDisassembly, false) \ 119 v(bool, asyncDisassembly, false) \ 119 120 v(bool, showDFGDisassembly, false) \ 120 121 v(bool, showFTLDisassembly, false) \ -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r181458 r181887 41 41 #include "DFGLongLivedState.h" 42 42 #include "DFGWorklist.h" 43 #include "Disassembler.h" 43 44 #include "ErrorInstance.h" 44 45 #include "FTLThunks.h" … … 306 307 #endif // ENABLE(DFG_JIT) 307 308 309 waitForAsynchronousDisassembly(); 310 308 311 // Clear this first to ensure that nobody tries to remove themselves from it. 309 312 m_perBytecodeProfiler = nullptr; -
trunk/Source/WTF/ChangeLog
r181845 r181887 1 2015-03-23 Filip Pizlo <fpizlo@apple.com> 2 3 JSC should have a low-cost asynchronous disassembler 4 https://bugs.webkit.org/show_bug.cgi?id=142997 5 6 Reviewed by Mark Lam. 7 8 * wtf/StringPrintStream.h: 9 1 10 2015-03-22 Benjamin Poulain <benjamin@webkit.org> 2 11 -
trunk/Source/WTF/wtf/StringPrintStream.h
r164384 r181887 38 38 WTF_EXPORT_PRIVATE virtual ~StringPrintStream(); 39 39 40 virtual void vprintf(const char* format, va_list) override WTF_ATTRIBUTE_PRINTF(2, 0);40 WTF_EXPORT_PRIVATE virtual void vprintf(const char* format, va_list) override WTF_ATTRIBUTE_PRINTF(2, 0); 41 41 42 42 WTF_EXPORT_PRIVATE CString toCString();
Note:
See TracChangeset
for help on using the changeset viewer.