1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 * vim: set ts=8 sts=4 et sw=4 tw=99: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef jswatchpoint_h 8 #define jswatchpoint_h 9 10 #include "jsalloc.h" 11 12 #include "gc/Barrier.h" 13 #include "js/HashTable.h" 14 15 namespace js { 16 17 struct WeakMapTracer; 18 19 struct WatchKey { WatchKeyWatchKey20 WatchKey() {} WatchKeyWatchKey21 WatchKey(JSObject* obj, jsid id) : object(obj), id(id) {} WatchKeyWatchKey22 WatchKey(const WatchKey& key) : object(key.object.get()), id(key.id.get()) {} 23 24 // These are traced unconditionally during minor GC, so do not require 25 // post-barriers. 26 PreBarrieredObject object; 27 PreBarrieredId id; 28 29 bool operator!=(const WatchKey& other) const { 30 return object != other.object || id != other.id; 31 } 32 }; 33 34 typedef bool 35 (* JSWatchPointHandler)(JSContext* cx, JSObject* obj, jsid id, JS::Value old, 36 JS::Value* newp, void* closure); 37 38 struct Watchpoint { 39 JSWatchPointHandler handler; 40 PreBarrieredObject closure; /* This is always marked in minor GCs and so doesn't require a postbarrier. */ 41 bool held; /* true if currently running handler */ WatchpointWatchpoint42 Watchpoint(JSWatchPointHandler handler, JSObject* closure, bool held) 43 : handler(handler), closure(closure), held(held) {} 44 }; 45 46 struct WatchKeyHasher 47 { 48 typedef WatchKey Lookup; 49 static inline js::HashNumber hash(const Lookup& key); 50 matchWatchKeyHasher51 static bool match(const WatchKey& k, const Lookup& l) { 52 return MovableCellHasher<PreBarrieredObject>::match(k.object, l.object) && 53 DefaultHasher<PreBarrieredId>::match(k.id, l.id); 54 } 55 rekeyWatchKeyHasher56 static void rekey(WatchKey& k, const WatchKey& newKey) { 57 k.object.unsafeSet(newKey.object); 58 k.id.unsafeSet(newKey.id); 59 } 60 }; 61 62 class WatchpointMap { 63 public: 64 typedef HashMap<WatchKey, Watchpoint, WatchKeyHasher, SystemAllocPolicy> Map; 65 66 bool init(); 67 bool watch(JSContext* cx, HandleObject obj, HandleId id, 68 JSWatchPointHandler handler, HandleObject closure); 69 void unwatch(JSObject* obj, jsid id, 70 JSWatchPointHandler* handlerp, JSObject** closurep); 71 void unwatchObject(JSObject* obj); 72 void clear(); 73 74 bool triggerWatchpoint(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp); 75 76 bool markIteratively(JSTracer* trc); 77 void markAll(JSTracer* trc); 78 static void sweepAll(JSRuntime* rt); 79 void sweep(); 80 81 static void traceAll(WeakMapTracer* trc); 82 void trace(WeakMapTracer* trc); 83 84 private: 85 Map map; 86 }; 87 88 } // namespace js 89 90 #endif /* jswatchpoint_h */ 91