Bug 989414 - Convert FixedHeapPtr to take a T* as template parameter instead of T; r=jonco
authorTerrence Cole <terrence@mozilla.com>
Fri, 25 Apr 2014 14:22:27 -0700
changeset 181207 d8a34e6f01f499a492a63bd5726e9ad56673d422
parent 181206 22e59b8c5b2ff04ccba32c4f7e1b0f5a3e9d4860
child 181208 3a821ea694d7631ad683057ed65198b32eaadc36
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersjonco
bugs989414
milestone32.0a1
Bug 989414 - Convert FixedHeapPtr to take a T* as template parameter instead of T; r=jonco
js/src/gc/Barrier.h
js/src/jsatom.cpp
js/src/jsatominlines.h
js/src/vm/Runtime.h
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -540,41 +540,42 @@ class HeapPtr : public BarrieredPtr<T>
      * and are deleted here. Please note that not all containers support move
      * semantics, so this does not completely prevent invalid uses.
      */
     HeapPtr(HeapPtr<T> &&) MOZ_DELETE;
     HeapPtr<T> &operator=(HeapPtr<T> &&) MOZ_DELETE;
 };
 
 /*
- * FixedHeapPtr is designed for one very narrow case: replacing immutable raw
- * pointers to GC-managed things, implicitly converting to a handle type for
- * ease of use.  Pointers encapsulated by this type must:
+ * ImmutableTenuredPtr is designed for one very narrow case: replacing
+ * immutable raw pointers to GC-managed things, implicitly converting to a
+ * handle type for ease of use. Pointers encapsulated by this type must:
  *
  *   be immutable (no incremental write barriers),
  *   never point into the nursery (no generational write barriers), and
  *   be traced via MarkRuntime (we use fromMarkedLocation).
  *
  * In short: you *really* need to know what you're doing before you use this
  * class!
  */
-template <class T>
-class FixedHeapPtr
+template <typename T>
+class ImmutableTenuredPtr
 {
-    T *value;
+    T value;
 
   public:
-    operator T*() const { return value; }
-    T * operator->() const { return value; }
+    operator T() const { return value; }
+    T operator->() const { return value; }
 
-    operator Handle<T*>() const {
-        return Handle<T*>::fromMarkedLocation(&value);
+    operator Handle<T>() const {
+        return Handle<T>::fromMarkedLocation(&value);
     }
 
-    void init(T *ptr) {
+    void init(T ptr) {
+        JS_ASSERT(ptr->isTenured());
         value = ptr;
     }
 };
 
 /*
  * A pre- and post-barriered heap pointer, for use inside the JS engine.
  *
  * Unlike HeapPtr<T>, it can be used in memory that is not managed by the GC,
@@ -723,16 +724,18 @@ typedef EncapsulatedPtr<Value> Encapsula
 typedef RelocatablePtr<Value> RelocatableValue;
 typedef HeapPtr<Value> HeapValue;
 
 typedef BarrieredPtr<jsid> BarrieredId;
 typedef EncapsulatedPtr<jsid> EncapsulatedId;
 typedef RelocatablePtr<jsid> RelocatableId;
 typedef HeapPtr<jsid> HeapId;
 
+typedef ImmutableTenuredPtr<PropertyName*> ImmutablePropertyNamePtr;
+
 /* Useful for hashtables with a HeapPtr as key. */
 template <class T>
 struct HeapPtrHasher
 {
     typedef HeapPtr<T> Key;
     typedef T Lookup;
 
     static HashNumber hash(Lookup obj) { return DefaultHasher<T>::hash(obj); }
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -144,17 +144,17 @@ JSRuntime::initializeAtoms(JSContext *cx
         JS_FOR_EACH_PROTOTYPE(COMMON_NAME_INFO)
 #undef COMMON_NAME_INFO
     };
 
     commonNames = cx->new_<JSAtomState>();
     if (!commonNames)
         return false;
 
-    FixedHeapPtr<PropertyName> *names = reinterpret_cast<FixedHeapPtr<PropertyName> *>(commonNames);
+    ImmutablePropertyNamePtr *names = reinterpret_cast<ImmutablePropertyNamePtr *>(commonNames);
     for (size_t i = 0; i < ArrayLength(cachedNames); i++, names++) {
         JSAtom *atom = Atomize(cx, cachedNames[i].str, cachedNames[i].length, InternAtom);
         if (!atom)
             return false;
         names->init(atom->asPropertyName());
     }
     JS_ASSERT(uintptr_t(names) == uintptr_t(commonNames + 1));
 
--- a/js/src/jsatominlines.h
+++ b/js/src/jsatominlines.h
@@ -153,28 +153,28 @@ AtomHasher::match(const AtomStateEntry &
     return mozilla::PodEqual(key->chars(), lookup.chars, lookup.length);
 }
 
 inline Handle<PropertyName*>
 TypeName(JSType type, const JSAtomState &names)
 {
     JS_ASSERT(type < JSTYPE_LIMIT);
     JS_STATIC_ASSERT(offsetof(JSAtomState, undefined) +
-                     JSTYPE_LIMIT * sizeof(FixedHeapPtr<PropertyName>) <=
+                     JSTYPE_LIMIT * sizeof(ImmutablePropertyNamePtr) <=
                      sizeof(JSAtomState));
     JS_STATIC_ASSERT(JSTYPE_VOID == 0);
     return (&names.undefined)[type];
 }
 
 inline Handle<PropertyName*>
 ClassName(JSProtoKey key, JSAtomState &atomState)
 {
     JS_ASSERT(key < JSProto_LIMIT);
     JS_STATIC_ASSERT(offsetof(JSAtomState, Null) +
-                     JSProto_LIMIT * sizeof(FixedHeapPtr<PropertyName>) <=
+                     JSProto_LIMIT * sizeof(ImmutablePropertyNamePtr) <=
                      sizeof(JSAtomState));
     JS_STATIC_ASSERT(JSProto_Null == 0);
     return (&atomState.Null)[key];
 }
 
 inline Handle<PropertyName*>
 ClassName(JSProtoKey key, JSRuntime *rt)
 {
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -447,32 +447,32 @@ class FreeOp : public JSFreeOp {
 
 namespace JS {
 struct RuntimeSizes;
 }
 
 /* Various built-in or commonly-used names pinned on first context. */
 struct JSAtomState
 {
-#define PROPERTYNAME_FIELD(idpart, id, text) js::FixedHeapPtr<js::PropertyName> id;
+#define PROPERTYNAME_FIELD(idpart, id, text) js::ImmutablePropertyNamePtr id;
     FOR_EACH_COMMON_PROPERTYNAME(PROPERTYNAME_FIELD)
 #undef PROPERTYNAME_FIELD
-#define PROPERTYNAME_FIELD(name, code, init, clasp) js::FixedHeapPtr<js::PropertyName> name;
+#define PROPERTYNAME_FIELD(name, code, init, clasp) js::ImmutablePropertyNamePtr name;
     JS_FOR_EACH_PROTOTYPE(PROPERTYNAME_FIELD)
 #undef PROPERTYNAME_FIELD
 };
 
 namespace js {
 
 #define NAME_OFFSET(name)       offsetof(JSAtomState, name)
 
 inline HandlePropertyName
 AtomStateOffsetToName(const JSAtomState &atomState, size_t offset)
 {
-    return *(js::FixedHeapPtr<js::PropertyName>*)((char*)&atomState + offset);
+    return *reinterpret_cast<js::ImmutablePropertyNamePtr *>((char*)&atomState + offset);
 }
 
 // There are several coarse locks in the enum below. These may be either
 // per-runtime or per-process. When acquiring more than one of these locks,
 // the acquisition must be done in the order below to avoid deadlocks.
 enum RuntimeLock {
     ExclusiveAccessLock,
     WorkerThreadStateLock,