bool WatchpointMap::triggerWatchpoint(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp) { Map::Ptr p = map.lookup(WatchKey(obj, id)); if (!p || p->value().held) return true; AutoEntryHolder holder(cx, map, p); /* Copy the entry, since GC would invalidate p. */ JSWatchPointHandler handler = p->value().handler; RootedObject closure(cx, p->value().closure); /* Determine the property's old value. */ Value old; old.setUndefined(); if (obj->isNative()) { NativeObject* nobj = &obj->as<NativeObject>(); if (Shape* shape = nobj->lookup(cx, id)) { if (shape->hasSlot()) old = nobj->getSlot(shape->slot()); } } // Read barrier to prevent an incorrectly gray closure from escaping the // watchpoint. See the comment before UnmarkGrayChildren in gc/Marking.cpp JS::ExposeObjectToActiveJS(closure); /* Call the handler. */ return handler(cx, obj, id, old, vp.address(), closure); }
void deallocateSigId(const Sig& sig, const void* sigId) { Map::Ptr p = map_.lookup(sig); MOZ_RELEASE_ASSERT(p && p->key() == sigId && p->value() > 0); p->value()--; if (!p->value()) { js_delete(p->key()); map_.remove(p); } }
void InnerViewTable::sweepAfterMinorGC(JSRuntime* rt) { MOZ_ASSERT(needsSweepAfterMinorGC()); if (nurseryKeysValid) { for (size_t i = 0; i < nurseryKeys.length(); i++) { JSObject* key = nurseryKeys[i]; Map::Ptr p = map.lookup(key); if (!p) continue; if (sweepEntry(&key, p->value())) map.remove(nurseryKeys[i]); else map.rekeyIfMoved(nurseryKeys[i], key); } nurseryKeys.clear(); } else { // Do the required sweeping by looking at every map entry. nurseryKeys.clear(); sweep(rt); nurseryKeysValid = true; } }
InnerViewTable::ViewVector* InnerViewTable::maybeViewsUnbarriered(ArrayBufferObject* buffer) { if (!map.initialized()) return nullptr; Map::Ptr p = map.lookup(buffer); if (p) return &p->value(); return nullptr; }
void InnerViewTable::sweepAfterMinorGC() { MOZ_ASSERT(needsSweepAfterMinorGC()); if (nurseryKeysValid) { for (size_t i = 0; i < nurseryKeys.length(); i++) { JSObject* buffer = MaybeForwarded(nurseryKeys[i]); Map::Ptr p = map.lookup(buffer); if (!p) continue; if (sweepEntry(&p->mutableKey(), p->value())) map.remove(buffer); } nurseryKeys.clear(); } else { // Do the required sweeping by looking at every map entry. nurseryKeys.clear(); sweep(); nurseryKeysValid = true; } }