Changeset 170564 in webkit
- Timestamp:
- Jun 27, 2014, 10:43:05 PM (11 years ago)
- Location:
- branches/ftlopt
- Files:
-
- 1 added
- 2 deleted
- 38 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/ftlopt/Source/JavaScriptCore/ChangeLog
r170556 r170564 1 2014-06-25 Filip Pizlo <fpizlo@apple.com> 2 3 [ftlopt] If a CodeBlock is jettisoned due to a watchpoint then it should be possible to figure out something about that watchpoint 4 https://bugs.webkit.org/show_bug.cgi?id=134333 5 6 Reviewed by Geoffrey Garen. 7 8 This is engineered to provide loads of information to the profiler without incurring any 9 costs when the profiler is disabled. It's the oldest trick in the book: the thing that 10 fires the watchpoint doesn't actually create anything to describe the reason why it was 11 fired; instead it creates a stack-allocated FireDetail subclass instance. Only if the 12 FireDetail::dump() virtual method is called does anything happen. 13 14 Currently we use this to produce very fine-grained data for Structure watchpoints and 15 some cases of variable watchpoints. For all other situations, the given reason is just a 16 string constant, by using StringFireDetail. If we find a situation where that string 17 constant is insufficient to diagnose an issue then we can change it to provide more 18 fine-grained information. 19 20 * JavaScriptCore.xcodeproj/project.pbxproj: 21 * bytecode/CodeBlock.cpp: 22 (JSC::CodeBlock::CodeBlock): 23 (JSC::CodeBlock::jettison): 24 * bytecode/CodeBlock.h: 25 * bytecode/CodeBlockJettisoningWatchpoint.cpp: 26 (JSC::CodeBlockJettisoningWatchpoint::fireInternal): 27 * bytecode/CodeBlockJettisoningWatchpoint.h: 28 * bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp: Removed. 29 * bytecode/ProfiledCodeBlockJettisoningWatchpoint.h: Removed. 30 * bytecode/StructureStubClearingWatchpoint.cpp: 31 (JSC::StructureStubClearingWatchpoint::fireInternal): 32 * bytecode/StructureStubClearingWatchpoint.h: 33 * bytecode/VariableWatchpointSet.h: 34 (JSC::VariableWatchpointSet::invalidate): 35 (JSC::VariableWatchpointSet::finalizeUnconditionally): 36 * bytecode/VariableWatchpointSetInlines.h: 37 (JSC::VariableWatchpointSet::notifyWrite): 38 * bytecode/Watchpoint.cpp: 39 (JSC::StringFireDetail::dump): 40 (JSC::WatchpointSet::fireAll): 41 (JSC::WatchpointSet::fireAllSlow): 42 (JSC::WatchpointSet::fireAllWatchpoints): 43 (JSC::InlineWatchpointSet::fireAll): 44 * bytecode/Watchpoint.h: 45 (JSC::FireDetail::FireDetail): 46 (JSC::FireDetail::~FireDetail): 47 (JSC::StringFireDetail::StringFireDetail): 48 (JSC::Watchpoint::fire): 49 (JSC::WatchpointSet::fireAll): 50 (JSC::WatchpointSet::touch): 51 (JSC::WatchpointSet::invalidate): 52 (JSC::InlineWatchpointSet::fireAll): 53 (JSC::InlineWatchpointSet::touch): 54 * dfg/DFGCommonData.h: 55 * dfg/DFGOperations.cpp: 56 * interpreter/Interpreter.cpp: 57 (JSC::Interpreter::execute): 58 * jsc.cpp: 59 (WTF::Masquerader::create): 60 * profiler/ProfilerCompilation.cpp: 61 (JSC::Profiler::Compilation::setJettisonReason): 62 (JSC::Profiler::Compilation::toJS): 63 * profiler/ProfilerCompilation.h: 64 (JSC::Profiler::Compilation::setJettisonReason): Deleted. 65 * runtime/ArrayBuffer.cpp: 66 (JSC::ArrayBuffer::transfer): 67 * runtime/ArrayBufferNeuteringWatchpoint.cpp: 68 (JSC::ArrayBufferNeuteringWatchpoint::fireAll): 69 * runtime/ArrayBufferNeuteringWatchpoint.h: 70 * runtime/CommonIdentifiers.h: 71 * runtime/CommonSlowPaths.cpp: 72 (JSC::SLOW_PATH_DECL): 73 * runtime/Identifier.cpp: 74 (JSC::Identifier::dump): 75 * runtime/Identifier.h: 76 * runtime/JSFunction.cpp: 77 (JSC::JSFunction::put): 78 (JSC::JSFunction::defineOwnProperty): 79 * runtime/JSGlobalObject.cpp: 80 (JSC::JSGlobalObject::addFunction): 81 (JSC::JSGlobalObject::haveABadTime): 82 * runtime/JSSymbolTableObject.cpp: 83 (JSC::VariableWriteFireDetail::dump): 84 * runtime/JSSymbolTableObject.h: 85 (JSC::VariableWriteFireDetail::VariableWriteFireDetail): 86 (JSC::symbolTablePut): 87 (JSC::symbolTablePutWithAttributes): 88 * runtime/PropertyName.h: 89 (JSC::PropertyName::dump): 90 * runtime/Structure.cpp: 91 (JSC::Structure::notifyTransitionFromThisStructure): 92 * runtime/Structure.h: 93 (JSC::Structure::notifyTransitionFromThisStructure): Deleted. 94 * runtime/SymbolTable.cpp: 95 (JSC::SymbolTableEntry::notifyWriteSlow): 96 (JSC::SymbolTable::WatchpointCleanup::finalizeUnconditionally): 97 * runtime/SymbolTable.h: 98 (JSC::SymbolTableEntry::notifyWrite): 99 * runtime/VM.cpp: 100 (JSC::VM::addImpureProperty): 101 1 102 2014-06-27 Michael Saboff <msaboff@apple.com> 2 103 -
branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r170490 r170564 478 478 0FC97F33182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F2F182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp */; }; 479 479 0FC97F34182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F30182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; }; 480 0FC97F35182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F31182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp */; };481 0FC97F36182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F32182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };482 480 0FC97F3D18202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F3718202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp */; }; 483 481 0FC97F3E18202119002C9B26 /* DFGInvalidationPointInjectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F3818202119002C9B26 /* DFGInvalidationPointInjectionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 486 484 0FC97F4118202119002C9B26 /* DFGWatchpointCollectionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F3B18202119002C9B26 /* DFGWatchpointCollectionPhase.cpp */; }; 487 485 0FC97F4218202119002C9B26 /* DFGWatchpointCollectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F3C18202119002C9B26 /* DFGWatchpointCollectionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; }; 486 0FCA9113195E66A000426438 /* VariableWatchpointSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCA9112195E66A000426438 /* VariableWatchpointSet.cpp */; }; 488 487 0FCCAE4516D0CF7400D0C65B /* ParserError.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCCAE4316D0CF6E00D0C65B /* ParserError.h */; settings = {ATTRIBUTES = (Private, ); }; }; 489 488 0FCEFAAB1804C13E00472CE4 /* FTLSaveRestore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */; }; … … 2663 2662 0FC97F2F182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeBlockJettisoningWatchpoint.cpp; sourceTree = "<group>"; }; 2664 2663 0FC97F30182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockJettisoningWatchpoint.h; sourceTree = "<group>"; }; 2665 0FC97F31182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProfiledCodeBlockJettisoningWatchpoint.cpp; sourceTree = "<group>"; };2666 0FC97F32182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfiledCodeBlockJettisoningWatchpoint.h; sourceTree = "<group>"; };2667 2664 0FC97F3718202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGInvalidationPointInjectionPhase.cpp; path = dfg/DFGInvalidationPointInjectionPhase.cpp; sourceTree = "<group>"; }; 2668 2665 0FC97F3818202119002C9B26 /* DFGInvalidationPointInjectionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInvalidationPointInjectionPhase.h; path = dfg/DFGInvalidationPointInjectionPhase.h; sourceTree = "<group>"; }; … … 2671 2668 0FC97F3B18202119002C9B26 /* DFGWatchpointCollectionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGWatchpointCollectionPhase.cpp; path = dfg/DFGWatchpointCollectionPhase.cpp; sourceTree = "<group>"; }; 2672 2669 0FC97F3C18202119002C9B26 /* DFGWatchpointCollectionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGWatchpointCollectionPhase.h; path = dfg/DFGWatchpointCollectionPhase.h; sourceTree = "<group>"; }; 2670 0FCA9112195E66A000426438 /* VariableWatchpointSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableWatchpointSet.cpp; sourceTree = "<group>"; }; 2673 2671 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlotVisitorInlines.h; sourceTree = "<group>"; }; 2674 2672 0FCCAE4316D0CF6E00D0C65B /* ParserError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserError.h; sourceTree = "<group>"; }; … … 5411 5409 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */, 5412 5410 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */, 5413 522ABAF9194A8043008B1C85 /* TypeLocation.h */,5414 5411 0FB5467C14F5CFD3002C2989 /* MethodOfGettingAValueProfile.cpp */, 5415 5412 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */, … … 5426 5423 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */, 5427 5424 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */, 5428 0FC97F31182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp */,5429 0FC97F32182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h */,5430 5425 0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */, 5431 5426 0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */, … … 5449 5444 0F7AB82C1958DA1C00C6881F /* ToThisStatus.cpp */, 5450 5445 0F7AB82D1958DA1C00C6881F /* ToThisStatus.h */, 5451 52 DAD38E195A164E00F30464/* TypeLocation.h */,5446 522ABAF9194A8043008B1C85 /* TypeLocation.h */, 5452 5447 A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */, 5453 5448 A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */, … … 5457 5452 0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */, 5458 5453 0F426A451460CBAB00131F8F /* ValueRecovery.h */, 5454 0FCA9112195E66A000426438 /* VariableWatchpointSet.cpp */, 5459 5455 0F9181C618415CA50057B669 /* VariableWatchpointSet.h */, 5460 5456 FE5248F8191442D900B7FDE4 /* VariableWatchpointSetInlines.h */, … … 5462 5458 0F919D2215853CDE004A4E7D /* Watchpoint.cpp */, 5463 5459 0F919D2315853CDE004A4E7D /* Watchpoint.h */, 5460 52DAD38E195A164E00F30464 /* TypeLocation.h */, 5464 5461 ); 5465 5462 path = bytecode; … … 6565 6562 868916B0155F286300CB2B9A /* PrivateName.h in Headers */, 6566 6563 BC18C4500E16F5CD00B34460 /* Profile.h in Headers */, 6567 0FC97F36182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h in Headers */,6568 6564 95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */, 6569 6565 BC18C4510E16F5CD00B34460 /* ProfileNode.h in Headers */, … … 7666 7662 C2981FDC17BAFF4400A3BC98 /* DFGDesiredWriteBarriers.cpp in Sources */, 7667 7663 0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */, 7664 0FCA9113195E66A000426438 /* VariableWatchpointSet.cpp in Sources */, 7668 7665 0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */, 7669 7666 0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */, … … 8005 8002 0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */, 8006 8003 95742F650DD11F5A000917FB /* Profile.cpp in Sources */, 8007 0FC97F35182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp in Sources */,8008 8004 95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */, 8009 8005 95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */, -
branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r170490 r170564 40 40 #include "DFGWorklist.h" 41 41 #include "Debugger.h" 42 #include "FunctionExecutableDump.h" 42 43 #include "HighFidelityTypeProfiler.h" 43 44 #include "Interpreter.h" … … 1552 1553 } 1553 1554 1555 namespace { 1556 1557 class PutToScopeFireDetail : public FireDetail { 1558 public: 1559 PutToScopeFireDetail(CodeBlock* codeBlock, const Identifier& ident) 1560 : m_codeBlock(codeBlock) 1561 , m_ident(ident) 1562 { 1563 } 1564 1565 virtual void dump(PrintStream& out) const override 1566 { 1567 out.print("Linking put_to_scope in ", FunctionExecutableDump(jsCast<FunctionExecutable*>(m_codeBlock->ownerExecutable())), " for ", m_ident); 1568 } 1569 1570 private: 1571 CodeBlock* m_codeBlock; 1572 const Identifier& m_ident; 1573 }; 1574 1575 } // anonymous namespace 1576 1554 1577 CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other) 1555 1578 : m_globalObject(other.m_globalObject) … … 1906 1929 else if (op.type == ClosureVar || op.type == ClosureVarWithVarInjectionChecks) { 1907 1930 if (op.watchpointSet) 1908 op.watchpointSet->invalidate( );1931 op.watchpointSet->invalidate(PutToScopeFireDetail(this, ident)); 1909 1932 } else if (op.structure) 1910 1933 instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure); … … 2967 2990 #endif 2968 2991 2969 void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode )2992 void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail) 2970 2993 { 2971 2994 RELEASE_ASSERT(reason != Profiler::NotJettisoned); … … 2976 2999 if (mode == CountReoptimization) 2977 3000 dataLog(" and counting reoptimization"); 2978 dataLog(" due to ", reason, ".\n"); 3001 dataLog(" due to ", reason); 3002 if (detail) 3003 dataLog(", ", *detail); 3004 dataLog(".\n"); 2979 3005 } 2980 3006 … … 2983 3009 2984 3010 if (Profiler::Compilation* compilation = jitCode()->dfgCommon()->compilation.get()) 2985 compilation->setJettisonReason(reason );3011 compilation->setJettisonReason(reason, detail); 2986 3012 2987 3013 // We want to accomplish two things here: -
branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.h
r170490 r170564 313 313 #endif 314 314 315 void jettison(Profiler::JettisonReason, ReoptimizationMode = DontCountReoptimization );315 void jettison(Profiler::JettisonReason, ReoptimizationMode = DontCountReoptimization, const FireDetail* = nullptr); 316 316 317 317 ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); } -
branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.cpp
r163844 r170564 33 33 namespace JSC { 34 34 35 void CodeBlockJettisoningWatchpoint::fireInternal( )35 void CodeBlockJettisoningWatchpoint::fireInternal(const FireDetail& detail) 36 36 { 37 37 if (DFG::shouldShowDisassembly()) 38 38 dataLog("Firing watchpoint ", RawPointer(this), " on ", *m_codeBlock, "\n"); 39 39 40 m_codeBlock->jettison(Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization );40 m_codeBlock->jettison(Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization, &detail); 41 41 42 42 if (isOnList()) -
branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h
r162139 r170564 46 46 47 47 protected: 48 virtual void fireInternal( ) override;48 virtual void fireInternal(const FireDetail&) override; 49 49 50 50 private: -
branches/ftlopt/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp
r163844 r170564 45 45 } 46 46 47 void StructureStubClearingWatchpoint::fireInternal( )47 void StructureStubClearingWatchpoint::fireInternal(const FireDetail&) 48 48 { 49 49 // This will implicitly cause my own demise: stub reset removes all watchpoints. -
branches/ftlopt/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h
r164424 r170564 69 69 70 70 protected: 71 virtual void fireInternal( ) override;71 virtual void fireInternal(const FireDetail&) override; 72 72 73 73 private: -
branches/ftlopt/Source/JavaScriptCore/bytecode/VariableWatchpointSet.h
r168443 r170564 32 32 namespace JSC { 33 33 34 class JSObject; 34 35 class SymbolTable; 36 37 class VariableWriteFireDetail : public FireDetail { 38 public: 39 VariableWriteFireDetail(JSObject* object, const PropertyName& name) 40 : m_object(object) 41 , m_name(name) 42 { 43 } 44 45 virtual void dump(PrintStream&) const override; 46 47 private: 48 JSObject* m_object; 49 const PropertyName& m_name; 50 }; 35 51 36 52 class VariableWatchpointSet : public WatchpointSet { … … 58 74 JSValue inferredValue() const { return m_inferredValue.get(); } 59 75 60 inline void notifyWrite(VM&, JSValue); 76 void notifyWrite(VM&, JSValue, const FireDetail&); 77 JS_EXPORT_PRIVATE void notifyWrite(VM&, JSValue, JSObject* baseObject, const PropertyName&); 78 void notifyWrite(VM&, JSValue, const char* reason); 61 79 62 void invalidate( )80 void invalidate(const FireDetail& detail) 63 81 { 64 82 m_inferredValue.clear(); 65 WatchpointSet::invalidate( );83 WatchpointSet::invalidate(detail); 66 84 } 67 85 68 void finalizeUnconditionally( )86 void finalizeUnconditionally(const FireDetail& detail) 69 87 { 70 88 ASSERT(!!m_inferredValue == (state() == IsWatched)); … … 77 95 if (Heap::isMarked(cell)) 78 96 return; 79 invalidate( );97 invalidate(detail); 80 98 } 81 99 -
branches/ftlopt/Source/JavaScriptCore/bytecode/VariableWatchpointSetInlines.h
r168443 r170564 32 32 namespace JSC { 33 33 34 inline void VariableWatchpointSet::notifyWrite(VM& vm, JSValue value )34 inline void VariableWatchpointSet::notifyWrite(VM& vm, JSValue value, const FireDetail& detail) 35 35 { 36 36 ASSERT(!!value); … … 45 45 if (value == m_inferredValue.get()) 46 46 return; 47 invalidate( );47 invalidate(detail); 48 48 return; 49 49 … … 55 55 ASSERT_NOT_REACHED(); 56 56 } 57 57 58 58 } // namespace JSC 59 59 -
branches/ftlopt/Source/JavaScriptCore/bytecode/Watchpoint.cpp
r159545 r170564 1 1 /* 2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 33 33 namespace JSC { 34 35 void StringFireDetail::dump(PrintStream& out) const 36 { 37 out.print(m_string); 38 } 34 39 35 40 Watchpoint::~Watchpoint() … … 66 71 } 67 72 68 void WatchpointSet::fireAllSlow() 73 void WatchpointSet::fireAll(const char* reason) 74 { 75 fireAll(StringFireDetail(reason)); 76 } 77 78 void WatchpointSet::fireAllSlow(const FireDetail& detail) 69 79 { 70 80 ASSERT(state() == IsWatched); 71 81 72 82 WTF::storeStoreFence(); 73 fireAllWatchpoints( );83 fireAllWatchpoints(detail); 74 84 m_state = IsInvalidated; 75 85 WTF::storeStoreFence(); 76 86 } 77 87 78 void WatchpointSet::fireAllWatchpoints( )88 void WatchpointSet::fireAllWatchpoints(const FireDetail& detail) 79 89 { 80 90 while (!m_set.isEmpty()) 81 m_set.begin()->fire( );91 m_set.begin()->fire(detail); 82 92 } 83 93 … … 85 95 { 86 96 inflate()->add(watchpoint); 97 } 98 99 void InlineWatchpointSet::fireAll(const char* reason) 100 { 101 fireAll(StringFireDetail(reason)); 87 102 } 88 103 -
branches/ftlopt/Source/JavaScriptCore/bytecode/Watchpoint.h
r162777 r170564 1 1 /* 2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 29 29 #include <wtf/Atomics.h> 30 #include <wtf/PrintStream.h> 30 31 #include <wtf/SentinelLinkedList.h> 31 32 #include <wtf/ThreadSafeRefCounted.h> … … 33 34 namespace JSC { 34 35 36 class FireDetail { 37 public: 38 FireDetail() 39 { 40 } 41 42 virtual ~FireDetail() 43 { 44 } 45 46 virtual void dump(PrintStream&) const = 0; 47 }; 48 49 class StringFireDetail : public FireDetail { 50 public: 51 StringFireDetail(const char* string) 52 : m_string(string) 53 { 54 } 55 56 virtual void dump(PrintStream& out) const override; 57 58 private: 59 const char* m_string; 60 }; 61 35 62 class Watchpoint : public BasicRawSentinelNode<Watchpoint> { 36 63 public: … … 41 68 virtual ~Watchpoint(); 42 69 43 void fire( ) { fireInternal(); }70 void fire(const FireDetail& detail) { fireInternal(detail); } 44 71 45 72 protected: 46 virtual void fireInternal( ) = 0;73 virtual void fireInternal(const FireDetail&) = 0; 47 74 }; 48 75 … … 103 130 } 104 131 105 void fireAll( )132 void fireAll(const FireDetail& detail) 106 133 { 107 134 if (state() != IsWatched) 108 135 return; 109 fireAllSlow(); 110 } 111 112 void touch() 136 fireAllSlow(detail); 137 } 138 139 JS_EXPORT_PRIVATE void fireAll(const char* reason); 140 141 void touch(const FireDetail& detail) 113 142 { 114 143 if (state() == ClearWatchpoint) 115 144 startWatching(); 116 145 else 117 fireAll( );118 } 119 120 void invalidate( )146 fireAll(detail); 147 } 148 149 void invalidate(const FireDetail& detail) 121 150 { 122 151 if (state() == IsWatched) 123 fireAll( );152 fireAll(detail); 124 153 m_state = IsInvalidated; 125 154 } … … 128 157 int8_t* addressOfSetIsNotEmpty() { return &m_setIsNotEmpty; } 129 158 130 JS_EXPORT_PRIVATE void fireAllSlow( ); // Call only if you've checked isWatched.159 JS_EXPORT_PRIVATE void fireAllSlow(const FireDetail&); // Call only if you've checked isWatched. 131 160 132 161 private: 133 void fireAllWatchpoints( );162 void fireAllWatchpoints(const FireDetail&); 134 163 135 164 friend class InlineWatchpointSet; … … 207 236 } 208 237 209 void fireAll( )238 void fireAll(const FireDetail& detail) 210 239 { 211 240 if (isFat()) { 212 fat()->fireAll( );241 fat()->fireAll(detail); 213 242 return; 214 243 } … … 219 248 } 220 249 221 void touch() 250 JS_EXPORT_PRIVATE void fireAll(const char* reason); 251 252 void touch(const FireDetail& detail) 222 253 { 223 254 if (isFat()) { 224 fat()->touch( );255 fat()->touch(detail); 225 256 return; 226 257 } … … 232 263 } 233 264 265 void touch(const char* reason) 266 { 267 touch(StringFireDetail(reason)); 268 } 269 234 270 private: 235 271 static const uintptr_t IsThinFlag = 1; -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGCommonData.h
r167467 r170564 33 33 #include "InlineCallFrameSet.h" 34 34 #include "JSCell.h" 35 #include "ProfiledCodeBlockJettisoningWatchpoint.h"36 35 #include "ProfilerCompilation.h" 37 36 #include "SymbolTable.h" … … 97 96 Vector<WriteBarrier<JSCell>> weakReferences; 98 97 SegmentedVector<CodeBlockJettisoningWatchpoint, 1, 0> watchpoints; 99 SegmentedVector<ProfiledCodeBlockJettisoningWatchpoint, 1, 0> profiledWatchpoints;100 98 Vector<JumpReplacement> jumpReplacements; 101 99 -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGOperations.cpp
r168459 r170564 1025 1025 JSValue value = JSValue::decode(encodedValue); 1026 1026 1027 set->notifyWrite(vm, value );1027 set->notifyWrite(vm, value, "Executed NotifyWrite"); 1028 1028 } 1029 1029 -
branches/ftlopt/Source/JavaScriptCore/interpreter/Interpreter.cpp
r167313 r170564 1178 1178 BatchedTransitionOptimizer optimizer(vm, variableObject); 1179 1179 if (variableObject->next()) 1180 variableObject->globalObject()->varInjectionWatchpoint()->fireAll( );1180 variableObject->globalObject()->varInjectionWatchpoint()->fireAll("Executed eval, fired VarInjection watchpoint"); 1181 1181 1182 1182 for (unsigned i = 0; i < numVariables; ++i) { -
branches/ftlopt/Source/JavaScriptCore/jsc.cpp
r170490 r170564 166 166 static Masquerader* create(VM& vm, JSGlobalObject* globalObject) 167 167 { 168 globalObject->masqueradesAsUndefinedWatchpoint()->fireAll( );168 globalObject->masqueradesAsUndefinedWatchpoint()->fireAll("Masquerading object allocated"); 169 169 Structure* structure = createStructure(vm, globalObject, jsNull()); 170 170 Masquerader* result = new (NotNull, allocateCell<Masquerader>(vm.heap, sizeof(Masquerader))) Masquerader(vm, structure); -
branches/ftlopt/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp
r163844 r170564 31 31 #include "JSCInlines.h" 32 32 #include "ProfilerDatabase.h" 33 #include "Watchpoint.h" 33 34 #include <wtf/StringPrintStream.h> 34 35 … … 94 95 } 95 96 97 void Compilation::setJettisonReason(JettisonReason jettisonReason, const FireDetail* detail) 98 { 99 if (m_jettisonReason != NotJettisoned) 100 return; // We only care about the original jettison reason. 101 102 m_jettisonReason = jettisonReason; 103 if (detail) 104 m_additionalJettisonReason = toCString(*detail); 105 else 106 m_additionalJettisonReason = CString(); 107 } 108 96 109 JSValue Compilation::toJS(ExecState* exec) const 97 110 { … … 134 147 result->putDirect(exec->vm(), exec->propertyNames().numInlinedCalls, jsNumber(m_numInlinedCalls)); 135 148 result->putDirect(exec->vm(), exec->propertyNames().jettisonReason, jsString(exec, String::fromUTF8(toCString(m_jettisonReason)))); 149 if (!m_additionalJettisonReason.isNull()) 150 result->putDirect(exec->vm(), exec->propertyNames().additionalJettisonReason, jsString(exec, String::fromUTF8(m_additionalJettisonReason))); 136 151 137 152 return result; -
branches/ftlopt/Source/JavaScriptCore/profiler/ProfilerCompilation.h
r163254 r170564 40 40 #include <wtf/SegmentedVector.h> 41 41 42 namespace JSC { namespace Profiler { 42 namespace JSC { 43 44 class FireDetail; 45 46 namespace Profiler { 43 47 44 48 class Bytecodes; … … 70 74 OSRExit* addOSRExit(unsigned id, const OriginStack&, ExitKind, bool isWatchpoint); 71 75 72 void setJettisonReason(JettisonReason jettisonReason) 73 { 74 m_jettisonReason = jettisonReason; 75 } 76 void setJettisonReason(JettisonReason, const FireDetail*); 76 77 77 78 JSValue toJS(ExecState*) const; … … 81 82 CompilationKind m_kind; 82 83 JettisonReason m_jettisonReason; 84 CString m_additionalJettisonReason; 83 85 Vector<ProfiledBytecodes> m_profiledBytecodes; 84 86 Vector<CompiledBytecode> m_descriptions; -
branches/ftlopt/Source/JavaScriptCore/runtime/ArrayBuffer.cpp
r163844 r170564 58 58 view->neuter(); 59 59 else if (ArrayBufferNeuteringWatchpoint* watchpoint = jsDynamicCast<ArrayBufferNeuteringWatchpoint*>(cell)) 60 watchpoint-> set()->fireAll();60 watchpoint->fireAll(); 61 61 } 62 62 return true; -
branches/ftlopt/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp
r170129 r170564 61 61 } 62 62 63 void ArrayBufferNeuteringWatchpoint::fireAll() 64 { 65 set()->fireAll("Array buffer was neutered"); 66 } 67 63 68 } // namespace JSC 64 69 -
branches/ftlopt/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h
r160150 r170564 51 51 52 52 WatchpointSet* set() { return m_set.get(); } 53 54 void fireAll(); 53 55 54 56 private: -
branches/ftlopt/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r167313 r170564 63 63 macro(__lookupSetter__) \ 64 64 macro(add) \ 65 macro(additionalJettisonReason) \ 65 66 macro(anonymous) \ 66 67 macro(arguments) \ -
branches/ftlopt/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r170382 r170564 211 211 { 212 212 BEGIN(); 213 exec->codeBlock()->symbolTable()->m_functionEnteredOnce.touch( );213 exec->codeBlock()->symbolTable()->m_functionEnteredOnce.touch("Function (re)entered"); 214 214 END(); 215 215 } … … 272 272 JSValue value = OP_C(2).jsValue(); 273 273 if (VariableWatchpointSet* set = pc[3].u.watchpointSet) 274 set->notifyWrite(vm, value );274 set->notifyWrite(vm, value, "Executed op_captured_mov"); 275 275 RETURN(value); 276 276 } … … 283 283 JSValue value = JSFunction::create(vm, codeBlock->functionDecl(pc[2].u.operand), exec->scope()); 284 284 if (VariableWatchpointSet* set = pc[3].u.watchpointSet) 285 set->notifyWrite(vm, value );285 set->notifyWrite(vm, value, "Executed op_new_captured_func"); 286 286 RETURN(value); 287 287 } -
branches/ftlopt/Source/JavaScriptCore/runtime/Identifier.cpp
r165999 r170564 98 98 } 99 99 100 void Identifier::dump(PrintStream& out) const 101 { 102 if (impl()) 103 out.print(impl()); 104 else 105 out.print("<null identifier>"); 106 } 107 100 108 #ifndef NDEBUG 101 109 -
branches/ftlopt/Source/JavaScriptCore/runtime/Identifier.h
r165999 r170564 97 97 JS_EXPORT_PRIVATE static PassRef<StringImpl> add(VM*, const char*); 98 98 JS_EXPORT_PRIVATE static PassRef<StringImpl> add(ExecState*, const char*); 99 100 void dump(PrintStream&) const; 99 101 100 102 private: -
branches/ftlopt/Source/JavaScriptCore/runtime/JSFunction.cpp
r167313 r170564 418 418 thisObject->methodTable(exec->vm())->getOwnPropertySlot(thisObject, exec, propertyName, slot); 419 419 thisObject->m_allocationProfile.clear(); 420 thisObject->m_allocationProfileWatchpoint.fireAll( );420 thisObject->m_allocationProfileWatchpoint.fireAll("Store to prototype property of a function"); 421 421 // Don't allow this to be cached, since a [[Put]] must clear m_allocationProfile. 422 422 PutPropertySlot dontCache(thisObject); … … 465 465 thisObject->methodTable(exec->vm())->getOwnPropertySlot(thisObject, exec, propertyName, slot); 466 466 thisObject->m_allocationProfile.clear(); 467 thisObject->m_allocationProfileWatchpoint.fireAll( );467 thisObject->m_allocationProfileWatchpoint.fireAll("Store to prototype property of a function"); 468 468 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); 469 469 } -
branches/ftlopt/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r168443 r170564 263 263 registerAt(var.registerNumber).set(exec->vm(), this, value); 264 264 if (var.set) 265 var.set->notifyWrite(vm, value );265 var.set->notifyWrite(vm, value, VariableWriteFireDetail(this, propertyName)); 266 266 } 267 267 … … 562 562 // the assumption that it's safe to transition to a non-SlowPut array storage don't 563 563 // do so anymore. 564 m_havingABadTimeWatchpoint->fireAll( );564 m_havingABadTimeWatchpoint->fireAll("Having a bad time"); 565 565 ASSERT(isHavingABadTime()); // The watchpoint is what tells us that we're having a bad time. 566 566 -
branches/ftlopt/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
r168443 r170564 36 36 37 37 namespace JSC { 38 39 class JSSymbolTableObject; 38 40 39 41 class JSSymbolTableObject : public JSScope { … … 140 142 } 141 143 if (VariableWatchpointSet* set = iter->value.watchpointSet()) 142 set->notifyWrite(vm, value );144 set->notifyWrite(vm, value, object, propertyName); 143 145 reg = &object->registerAt(fastEntry.getIndex()); 144 146 } … … 167 169 ASSERT(!entry.isNull()); 168 170 if (VariableWatchpointSet* set = entry.watchpointSet()) 169 set->notifyWrite(vm, value );171 set->notifyWrite(vm, value, object, propertyName); 170 172 entry.setAttributes(attributes); 171 173 reg = &object->registerAt(entry.getIndex()); -
branches/ftlopt/Source/JavaScriptCore/runtime/PropertyName.h
r165999 r170564 107 107 return m_impl ? toUInt32FromStringImpl(m_impl) : NotAnIndex; 108 108 } 109 110 void dump(PrintStream& out) const 111 { 112 if (m_impl) 113 out.print(m_impl); 114 else 115 out.print("<null property name>"); 116 } 109 117 110 118 private: -
branches/ftlopt/Source/JavaScriptCore/runtime/Structure.cpp
r170490 r170564 1004 1004 } 1005 1005 1006 namespace { 1007 1008 class StructureFireDetail : public FireDetail { 1009 public: 1010 StructureFireDetail(const Structure* structure) 1011 : m_structure(structure) 1012 { 1013 } 1014 1015 virtual void dump(PrintStream& out) const override 1016 { 1017 out.print("Structure transition from ", *m_structure); 1018 } 1019 1020 private: 1021 const Structure* m_structure; 1022 }; 1023 1024 } // anonymous namespace 1025 1026 void Structure::notifyTransitionFromThisStructure() const 1027 { 1028 m_transitionWatchpointSet.fireAll(StructureFireDetail(this)); 1029 } 1030 1006 1031 JSValue Structure::prototypeForLookup(CodeBlock* codeBlock) const 1007 1032 { -
branches/ftlopt/Source/JavaScriptCore/runtime/Structure.h
r170490 r170564 365 365 } 366 366 367 void notifyTransitionFromThisStructure() const 368 { 369 m_transitionWatchpointSet.fireAll(); 370 } 367 void notifyTransitionFromThisStructure() const; 371 368 372 369 InlineWatchpointSet& transitionWatchpointSet() const -
branches/ftlopt/Source/JavaScriptCore/runtime/SymbolTable.cpp
r170490 r170564 80 80 } 81 81 82 void SymbolTableEntry::notifyWriteSlow(VM& vm, JSValue value )82 void SymbolTableEntry::notifyWriteSlow(VM& vm, JSValue value, const FireDetail& detail) 83 83 { 84 84 VariableWatchpointSet* watchpoints = fatEntry()->m_watchpoints.get(); … … 86 86 return; 87 87 88 watchpoints->notifyWrite(vm, value );88 watchpoints->notifyWrite(vm, value, detail); 89 89 } 90 90 … … 133 133 void SymbolTable::WatchpointCleanup::finalizeUnconditionally() 134 134 { 135 StringFireDetail detail("Symbol table clean-up during GC"); 135 136 Map::iterator iter = m_symbolTable->m_map.begin(); 136 137 Map::iterator end = m_symbolTable->m_map.end(); 137 138 for (; iter != end; ++iter) { 138 139 if (VariableWatchpointSet* set = iter->value.watchpointSet()) 139 set->finalizeUnconditionally( );140 set->finalizeUnconditionally(detail); 140 141 } 141 142 } -
branches/ftlopt/Source/JavaScriptCore/runtime/SymbolTable.h
r170490 r170564 231 231 } 232 232 233 ALWAYS_INLINE void notifyWrite(VM& vm, JSValue value )233 ALWAYS_INLINE void notifyWrite(VM& vm, JSValue value, const FireDetail& detail) 234 234 { 235 235 if (LIKELY(!isFat())) 236 236 return; 237 notifyWriteSlow(vm, value );237 notifyWriteSlow(vm, value, detail); 238 238 } 239 239 … … 259 259 260 260 SymbolTableEntry& copySlow(const SymbolTableEntry&); 261 JS_EXPORT_PRIVATE void notifyWriteSlow(VM&, JSValue );261 JS_EXPORT_PRIVATE void notifyWriteSlow(VM&, JSValue, const FireDetail&); 262 262 263 263 bool isFat() const -
branches/ftlopt/Source/JavaScriptCore/runtime/VM.cpp
r170490 r170564 906 906 { 907 907 if (RefPtr<WatchpointSet> watchpointSet = m_impurePropertyWatchpointSets.take(propertyName)) 908 watchpointSet->fireAll( );908 watchpointSet->fireAll("Impure property added"); 909 909 } 910 910 -
branches/ftlopt/Source/WebCore/ChangeLog
r170399 r170564 1 2014-06-25 Filip Pizlo <fpizlo@apple.com> 2 3 [ftlopt] If a CodeBlock is jettisoned due to a watchpoint then it should be possible to figure out something about that watchpoint 4 https://bugs.webkit.org/show_bug.cgi?id=134333 5 6 Reviewed by Geoffrey Garen. 7 8 No new tests because no change in behavior. 9 10 * bindings/scripts/CodeGeneratorJS.pm: 11 (GenerateHeader): 12 1 13 2014-06-24 Mark Lam <mark.lam@apple.com> 2 14 -
branches/ftlopt/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
r168385 r170564 865 865 push(@headerContent, " static $className* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, PassRefPtr<$implType> impl)\n"); 866 866 push(@headerContent, " {\n"); 867 push(@headerContent, " globalObject->masqueradesAsUndefinedWatchpoint()->fireAll( );\n");867 push(@headerContent, " globalObject->masqueradesAsUndefinedWatchpoint()->fireAll(\"Allocated masquerading object\");\n"); 868 868 push(@headerContent, " $className* ptr = new (NotNull, JSC::allocateCell<$className>(globalObject->vm().heap)) $className(structure, globalObject, impl);\n"); 869 869 push(@headerContent, " ptr->finishCreation(globalObject->vm());\n"); -
branches/ftlopt/Tools/ChangeLog
r168511 r170564 1 2014-06-25 Filip Pizlo <fpizlo@apple.com> 2 3 [ftlopt] If a CodeBlock is jettisoned due to a watchpoint then it should be possible to figure out something about that watchpoint 4 https://bugs.webkit.org/show_bug.cgi?id=134333 5 6 Reviewed by Geoffrey Garen. 7 8 * Scripts/display-profiler-output: 9 1 10 2014-05-08 David Farler <dfarler@apple.com> 2 11 -
branches/ftlopt/Tools/Scripts/display-profiler-output
r163259 r170564 332 332 attr_accessor :bytecode, :engine, :descriptions, :counters, :compilationIndex 333 333 attr_accessor :osrExits, :profiledBytecodes, :numInlinedGetByIds, :numInlinedPutByIds 334 attr_accessor :numInlinedCalls, :jettisonReason 334 attr_accessor :numInlinedCalls, :jettisonReason, :additionalJettisonReason 335 335 336 336 def initialize(json) … … 386 386 @numInlinedCalls = json["numInlinedCalls"] 387 387 @jettisonReason = json["jettisonReason"] 388 @additionalJettisonReason = json["additionalJettisonReason"] 388 389 end 389 390 … … 859 860 if compilation.jettisonReason != "NotJettisoned" 860 861 puts " Jettisoned due to #{compilation.jettisonReason}" 862 if compilation.additionalJettisonReason 863 puts " #{compilation.additionalJettisonReason}" 864 end 861 865 end 862 866 }
Note:
See TracChangeset
for help on using the changeset viewer.