Source/JavaScriptCore/ChangeLog

 12013-10-30 Filip Pizlo <fpizlo@apple.com>
 2
 3 Assertion failure in js/dom/global-constructors-attributes-dedicated-worker.html
 4 https://bugs.webkit.org/show_bug.cgi?id=123551
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 WatchpointSets have always had this "fire everything on deletion" policy because it
 9 seemed like a good fail-safe at the time I first implemented WatchpointSets. But
 10 it's actually causing bugs rather than providing safety:
 11
 12 - Everyone who registers Watchpoints with WatchpointSets have separate mechanisms
 13 for either keeping the WatchpointSets alive or noticing when they are collected.
 14 So this wasn't actually providing any safety.
 15
 16 One example of this is Structures, where:
 17
 18 - CodeBlocks that register Watchpoints on Structure's WatchpointSet will also
 19 register weak references to the Structure, and the GC will jettison a CodeBlock
 20 if the Structure(s) it cares about dies.
 21
 22 - StructureStubInfos that register Watchpoints on Structure's WatchpointSet will
 23 also be cleared by GC if the Structures die.
 24
 25 - The WatchpointSet constructor would get invoked from finalization/destruction.
 26 This would then cause CodeBlock::jettison() to be called on a CodeBlock, but that
 27 method requires doing things that access heap objects.
 28
 29 This also ensures that CodeBlock::jettison() cannot cause a GC. This is safe since
 30 that method doesn't really allocate objects, and it is likely necessary because
 31 jettison() may be called from deep in the stack.
 32
 33 * bytecode/CodeBlock.cpp:
 34 (JSC::CodeBlock::jettison):
 35 * bytecode/Watchpoint.cpp:
 36 (JSC::WatchpointSet::~WatchpointSet):
 37 * bytecode/Watchpoint.h:
 38
1392013-10-30 Mark Lam <mark.lam@apple.com>
240
341 Unreviewed, fix C Loop LLINT build.
158340

Source/JavaScriptCore/bytecode/CodeBlock.cpp

@@void CodeBlock::jettison(ReoptimizationM
28172817 dataLog(".\n");
28182818 }
28192819
2820  DeferGC deferGC(*m_heap);
 2820 DeferGCForAWhile deferGC(*m_heap);
28212821 RELEASE_ASSERT(JITCode::isOptimizingJIT(jitType()));
28222822
28232823 // We want to accomplish two things here:
158325

Source/JavaScriptCore/bytecode/Watchpoint.cpp

@@WatchpointSet::WatchpointSet(InitialWatc
4646
4747WatchpointSet::~WatchpointSet()
4848{
49  // Fire all watchpoints. This is necessary because it is possible, say with
50  // structure watchpoints, for the watchpoint set owner to die while the
51  // watchpoint owners are still live.
52  fireAllWatchpoints();
 49 // Remove all watchpoints, so that they don't try to remove themselves. Note that we
 50 // don't fire watchpoints on deletion. We assume that any code that is interested in
 51 // watchpoints already also separately has a mechanism to make sure that the code is
 52 // either keeping the watchpoint set's owner alive, or does some week reference thing.
 53 while (!m_set.isEmpty())
 54 m_set.begin()->remove();
5355}
5456
5557void WatchpointSet::add(Watchpoint* watchpoint)
158325

Source/JavaScriptCore/bytecode/Watchpoint.h

@@class WatchpointSet : public ThreadSafeR
5353 friend class LLIntOffsetsExtractor;
5454public:
5555 WatchpointSet(InitialWatchpointSetMode);
56  ~WatchpointSet();
 56 ~WatchpointSet(); // Note that this will not fire any of the watchpoints; if you need to know when a WatchpointSet dies then you need a separate mechanism for this.
5757
5858 // It is safe to call this from another thread. It may return true
5959 // even if the set actually had been invalidated, but that ought to happen
158325