X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/93a3786624b2768d89bfa27e46598dc64e2fb70a..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/bytecode/Watchpoint.cpp?ds=sidebyside diff --git a/bytecode/Watchpoint.cpp b/bytecode/Watchpoint.cpp index 75dfe8a..3c5f93a 100644 --- a/bytecode/Watchpoint.cpp +++ b/bytecode/Watchpoint.cpp @@ -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 @@ -26,52 +26,68 @@ #include "config.h" #include "Watchpoint.h" -#include "LinkBuffer.h" +#include #include 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(fat); return fat; }