From 5866349735f6fc83d2356238535d75348cd7278e Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Mon, 5 Mar 2018 18:03:56 -0800 Subject: [PATCH] Bug 1443592: Part 1: Introduce opaque LiveSavedFrameCache::Key type for cache keys. r=fitzgen By design, the LiveSavedFrameCache holds the addresses of both live and dead stack frames. This change wraps those addresses in an opaque type that can only be compared for equality with other such values, and provides no interface to retrieve the underlying pointer, ensuring statically that we will not accidentally use a cache key to access memory. MozReview-Commit-ID: 9Wom5gFVQls --HG-- extra : rebase_source : e3dff595085973f1f10f57a67c192656c0bcd866 --- js/src/vm/SavedStacks.cpp | 4 ++-- js/src/vm/Stack.h | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/js/src/vm/SavedStacks.cpp b/js/src/vm/SavedStacks.cpp index e2523af45697..1fc48ed84889 100644 --- a/js/src/vm/SavedStacks.cpp +++ b/js/src/vm/SavedStacks.cpp @@ -110,14 +110,14 @@ LiveSavedFrameCache::find(JSContext* cx, FrameIter& frameIter, MutableHandleSave Maybe maybeFramePtr = getFramePtr(frameIter); MOZ_ASSERT(maybeFramePtr.isSome()); - FramePtr framePtr(*maybeFramePtr); + Key key(*maybeFramePtr); const jsbytecode* pc = frameIter.pc(); size_t numberStillValid = 0; frame.set(nullptr); for (auto* p = frames->begin(); p < frames->end(); p++) { numberStillValid++; - if (framePtr == p->framePtr && pc == p->pc) { + if (key == p->key && pc == p->pc) { frame.set(p->savedFrame); break; } diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index 5a920a548d25..f2d5a8448fad 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -1173,14 +1173,27 @@ class LiveSavedFrameCache using FramePtr = mozilla::Variant; private: + // A key in the cache: the address of a frame, live or dead, for which we + // can cache SavedFrames. Since the pointer may not be live, the only + // operation this type permits is comparison. + class Key { + FramePtr framePtr; + + public: + MOZ_IMPLICIT Key(const FramePtr& framePtr) : framePtr(framePtr) { } + + bool operator==(const Key& rhs) const { return rhs.framePtr == this->framePtr; } + bool operator!=(const Key& rhs) const { return !(rhs == *this); } + }; + struct Entry { - const FramePtr framePtr; + const Key key; const jsbytecode* pc; HeapPtr savedFrame; - Entry(const FramePtr& framePtr, const jsbytecode* pc, SavedFrame* savedFrame) - : framePtr(framePtr) + Entry(const Key& key, const jsbytecode* pc, SavedFrame* savedFrame) + : key(key) , pc(pc) , savedFrame(savedFrame) { }