/*
- * 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)
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;
}