]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - bytecode/Watchpoint.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / bytecode / Watchpoint.cpp
index 75dfe8a76895ff03cabf5e04596bc06f7966fc9b..3c5f93a83e84cd7268ee52b8dcf6e2d9398abb44 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "Watchpoint.h"
 
-#include "LinkBuffer.h"
+#include <wtf/CompilationThread.h>
 #include <wtf/PassRefPtr.h>
 
 namespace JSC {
 
+void StringFireDetail::dump(PrintStream& out) const
+{
+    out.print(m_string);
+}
+
 Watchpoint::~Watchpoint()
 {
     if (isOnList())
         remove();
 }
 
-WatchpointSet::WatchpointSet(InitialWatchpointSetMode mode)
-    : m_isWatched(mode == InitializedWatching)
-    , m_isInvalidated(false)
+WatchpointSet::WatchpointSet(WatchpointState state)
+    : m_state(state)
+    , m_setIsNotEmpty(false)
 {
 }
 
 WatchpointSet::~WatchpointSet()
 {
-    // Fire all watchpoints. This is necessary because it is possible, say with
-    // structure watchpoints, for the watchpoint set owner to die while the
-    // watchpoint owners are still live.
-    fireAllWatchpoints();
+    // Remove all watchpoints, so that they don't try to remove themselves. Note that we
+    // don't fire watchpoints on deletion. We assume that any code that is interested in
+    // watchpoints already also separately has a mechanism to make sure that the code is
+    // either keeping the watchpoint set's owner alive, or does some weak reference thing.
+    while (!m_set.isEmpty())
+        m_set.begin()->remove();
 }
 
 void WatchpointSet::add(Watchpoint* watchpoint)
 {
+    ASSERT(!isCompilationThread());
+    ASSERT(state() != IsInvalidated);
     if (!watchpoint)
         return;
     m_set.push(watchpoint);
-    m_isWatched = true;
+    m_setIsNotEmpty = true;
+    m_state = IsWatched;
 }
 
-void WatchpointSet::notifyWriteSlow()
+void WatchpointSet::fireAllSlow(const FireDetail& detail)
 {
-    ASSERT(m_isWatched);
+    ASSERT(state() == IsWatched);
     
-    fireAllWatchpoints();
-    m_isWatched = false;
-    m_isInvalidated = true;
+    WTF::storeStoreFence();
+    fireAllWatchpoints(detail);
+    m_state = IsInvalidated;
+    WTF::storeStoreFence();
+}
+
+void WatchpointSet::fireAllSlow(const char* reason)
+{
+    fireAllSlow(StringFireDetail(reason));
 }
 
-void WatchpointSet::fireAllWatchpoints()
+void WatchpointSet::fireAllWatchpoints(const FireDetail& detail)
 {
     while (!m_set.isEmpty())
-        m_set.begin()->fire();
+        m_set.begin()->fire(detail);
 }
 
 void InlineWatchpointSet::add(Watchpoint* watchpoint)
@@ -79,14 +95,17 @@ void InlineWatchpointSet::add(Watchpoint* watchpoint)
     inflate()->add(watchpoint);
 }
 
+void InlineWatchpointSet::fireAll(const char* reason)
+{
+    fireAll(StringFireDetail(reason));
+}
+
 WatchpointSet* InlineWatchpointSet::inflateSlow()
 {
     ASSERT(isThin());
-    WatchpointSet* fat = adoptRef(new WatchpointSet(InitializedBlind)).leakRef();
-    if (m_data & IsInvalidatedFlag)
-        fat->m_isInvalidated = true;
-    if (m_data & IsWatchedFlag)
-        fat->m_isWatched = true;
+    ASSERT(!isCompilationThread());
+    WatchpointSet* fat = adoptRef(new WatchpointSet(decodeState(m_data))).leakRef();
+    WTF::storeStoreFence();
     m_data = bitwise_cast<uintptr_t>(fat);
     return fat;
 }