Line data Source code
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 : class GCMarker;
18 : struct WeakMapTracer;
19 :
20 0 : struct WatchKey {
21 : WatchKey() {}
22 0 : WatchKey(JSObject* obj, jsid id) : object(obj), id(id) {}
23 0 : WatchKey(const WatchKey& key) : object(key.object.get()), id(key.id.get()) {}
24 :
25 : // These are traced unconditionally during minor GC, so do not require
26 : // post-barriers.
27 : PreBarrieredObject object;
28 : PreBarrieredId id;
29 :
30 : bool operator!=(const WatchKey& other) const {
31 : return object != other.object || id != other.id;
32 : }
33 : };
34 :
35 : typedef bool
36 : (* JSWatchPointHandler)(JSContext* cx, JSObject* obj, jsid id, const JS::Value& old,
37 : JS::Value* newp, void* closure);
38 :
39 0 : struct Watchpoint {
40 : JSWatchPointHandler handler;
41 : PreBarrieredObject closure; /* This is always marked in minor GCs and so doesn't require a postbarrier. */
42 : bool held; /* true if currently running handler */
43 0 : Watchpoint(JSWatchPointHandler handler, JSObject* closure, bool held)
44 0 : : handler(handler), closure(closure), held(held) {}
45 : };
46 :
47 : struct WatchKeyHasher
48 : {
49 : typedef WatchKey Lookup;
50 : static inline js::HashNumber hash(const Lookup& key);
51 :
52 0 : static bool match(const WatchKey& k, const Lookup& l) {
53 0 : return MovableCellHasher<PreBarrieredObject>::match(k.object, l.object) &&
54 0 : DefaultHasher<PreBarrieredId>::match(k.id, l.id);
55 : }
56 :
57 0 : static void rekey(WatchKey& k, const WatchKey& newKey) {
58 0 : k.object.unsafeSet(newKey.object);
59 0 : k.id.unsafeSet(newKey.id);
60 0 : }
61 : };
62 :
63 0 : class WatchpointMap {
64 : public:
65 : typedef HashMap<WatchKey, Watchpoint, WatchKeyHasher, SystemAllocPolicy> Map;
66 :
67 : bool init();
68 : bool watch(JSContext* cx, HandleObject obj, HandleId id,
69 : JSWatchPointHandler handler, HandleObject closure);
70 : void unwatch(JSObject* obj, jsid id);
71 : void unwatchObject(JSObject* obj);
72 : void clear();
73 :
74 : bool triggerWatchpoint(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp);
75 :
76 : bool markIteratively(GCMarker* marker);
77 : void trace(JSTracer* trc);
78 :
79 : static void sweepAll(JSRuntime* rt);
80 : void sweep();
81 :
82 : static void traceAll(WeakMapTracer* trc);
83 : void trace(WeakMapTracer* trc);
84 :
85 : private:
86 : Map map;
87 : };
88 :
89 : } // namespace js
90 :
91 : #endif /* jswatchpoint_h */
|