Bug 1276028 - Baldr: tidy up IsPod specialization (r=bbouvier)
authorLuke Wagner <luke@mozilla.com>
Mon, 06 Jun 2016 17:18:55 -0500
changeset 376158 e85e9883c8fcef0e4a794a23e636e1df55bd05c2
parent 376157 f0d26f56bffd12f9c6fead1302ea63289e3c2b28
child 376159 ac03826cd5a83b7b91dedccd2cf9532cc82e350a
push id20510
push usercholler@mozilla.com
push dateTue, 07 Jun 2016 13:42:30 +0000
reviewersbbouvier
bugs1276028
milestone50.0a1
Bug 1276028 - Baldr: tidy up IsPod specialization (r=bbouvier) MozReview-Commit-ID: KfI00OvIupL
js/src/asmjs/WasmModule.h
js/src/asmjs/WasmTypes.h
--- a/js/src/asmjs/WasmModule.h
+++ b/js/src/asmjs/WasmModule.h
@@ -30,29 +30,16 @@ namespace js {
 
 class AsmJSModule;
 class WasmActivation;
 class WasmModuleObject;
 namespace jit { struct BaselineScript; }
 
 namespace wasm {
 
-// A wasm Module and everything it contains must support serialization,
-// deserialization and cloning. Some data can be simply copied as raw bytes and,
-// as a convention, is stored in an inline CacheablePod struct. Everything else
-// should implement the below methods which are called recusively by the
-// containing Module. See comments for these methods in wasm::Module.
-
-#define WASM_DECLARE_SERIALIZABLE(Type)                                         \
-    size_t serializedSize() const;                                              \
-    uint8_t* serialize(uint8_t* cursor) const;                                  \
-    const uint8_t* deserialize(ExclusiveContext* cx, const uint8_t* cursor);    \
-    MOZ_MUST_USE bool clone(JSContext* cx, Type* out) const;                    \
-    size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
-
 // The StaticLinkData contains all the metadata necessary to perform
 // Module::staticallyLink but is not necessary afterwards.
 
 struct StaticLinkData
 {
     struct InternalLink {
         enum Kind {
             RawPointer,
@@ -296,25 +283,17 @@ class CodeRange
             return offset >= rhs.begin() && offset < rhs.end();
         }
         bool operator<(const CodeRange& rhs) const {
             return offset < rhs.begin();
         }
     };
 };
 
-} // namespace wasm
-} // namespace js
-namespace mozilla {
-template <> struct IsPod<js::wasm::CodeRange> : TrueType {};
-}
-namespace js {
-namespace wasm {
-
-typedef Vector<CodeRange, 0, SystemAllocPolicy> CodeRangeVector;
+WASM_DECLARE_POD_VECTOR(CodeRange, CodeRangeVector)
 
 // A CallThunk describes the offset and target of thunks so that they may be
 // patched at runtime when profiling is toggled. Thunks are emitted to connect
 // callsites that are too far away from callees to fit in a single call
 // instruction's relative offset.
 
 struct CallThunk
 {
@@ -323,25 +302,17 @@ struct CallThunk
         uint32_t funcIndex;
         uint32_t codeRangeIndex;
     } u;
 
     CallThunk(uint32_t offset, uint32_t funcIndex) : offset(offset) { u.funcIndex = funcIndex; }
     CallThunk() = default;
 };
 
-typedef Vector<CallThunk, 0, SystemAllocPolicy> CallThunkVector;
-
-} // namespace wasm
-} // namespace js
-namespace mozilla {
-template <> struct IsPod<js::wasm::CallThunk> : TrueType {};
-}
-namespace js {
-namespace wasm {
+WASM_DECLARE_POD_VECTOR(CallThunk, CallThunkVector)
 
 // CacheableChars is used to cacheably store UniqueChars.
 
 struct CacheableChars : UniqueChars
 {
     CacheableChars() = default;
     explicit CacheableChars(char* ptr) : UniqueChars(ptr) {}
     MOZ_IMPLICIT CacheableChars(UniqueChars&& rhs) : UniqueChars(Move(rhs)) {}
--- a/js/src/asmjs/WasmTypes.h
+++ b/js/src/asmjs/WasmTypes.h
@@ -42,16 +42,39 @@ namespace wasm {
 using mozilla::DebugOnly;
 using mozilla::EnumeratedArray;
 using mozilla::Maybe;
 using mozilla::Move;
 using mozilla::MallocSizeOf;
 
 typedef Vector<uint32_t, 0, SystemAllocPolicy> Uint32Vector;
 
+// To call Vector::podResizeToFit, a type must specialize mozilla::IsPod
+// which is pretty verbose to do within js::wasm, so factor that process out
+// into a macro.
+
+#define WASM_DECLARE_POD_VECTOR(Type, VectorName)                               \
+} } namespace mozilla {                                                         \
+template <> struct IsPod<js::wasm::Type> : TrueType {};                         \
+} namespace js { namespace wasm {                                               \
+typedef Vector<Type, 0, SystemAllocPolicy> VectorName;
+
+// A wasm Module and everything it contains must support serialization,
+// deserialization and cloning. Some data can be simply copied as raw bytes and,
+// as a convention, is stored in an inline CacheablePod struct. Everything else
+// should implement the below methods which are called recusively by the
+// containing Module. See comments for these methods in wasm::Module.
+
+#define WASM_DECLARE_SERIALIZABLE(Type)                                         \
+    size_t serializedSize() const;                                              \
+    uint8_t* serialize(uint8_t* cursor) const;                                  \
+    const uint8_t* deserialize(ExclusiveContext* cx, const uint8_t* cursor);    \
+    MOZ_MUST_USE bool clone(JSContext* cx, Type* out) const;                    \
+    size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
+
 // ValType/ExprType utilities
 
 // ExprType::Limit is an out-of-band value and has no wasm-semantic meaning. For
 // the purpose of recursive validation, we use this value to represent the type
 // of branch/return instructions that don't actually return to the parent
 // expression and can thus be used in any context.
 const ExprType AnyType = ExprType::Limit;
 
@@ -508,41 +531,33 @@ class CallSite : public CallSiteDesc
 
     // The stackDepth measures the amount of stack space pushed since the
     // function was called. In particular, this includes the pushed return
     // address on all archs (whether or not the call instruction pushes the
     // return address (x86/x64) or the prologue does (ARM/MIPS)).
     uint32_t stackDepth() const { return stackDepth_; }
 };
 
+WASM_DECLARE_POD_VECTOR(CallSite, CallSiteVector)
+
 class CallSiteAndTarget : public CallSite
 {
     uint32_t targetIndex_;
 
   public:
     CallSiteAndTarget(CallSite cs, uint32_t targetIndex)
       : CallSite(cs), targetIndex_(targetIndex)
     { }
 
     static const uint32_t NOT_INTERNAL = UINT32_MAX;
 
     bool isInternal() const { return targetIndex_ != NOT_INTERNAL; }
     uint32_t targetIndex() const { MOZ_ASSERT(isInternal()); return targetIndex_; }
 };
 
-} // namespace wasm
-} // namespace js
-namespace mozilla {
-template <> struct IsPod<js::wasm::CallSite>          : TrueType {};
-template <> struct IsPod<js::wasm::CallSiteAndTarget> : TrueType {};
-}
-namespace js {
-namespace wasm {
-
-typedef Vector<CallSite, 0, SystemAllocPolicy> CallSiteVector;
 typedef Vector<CallSiteAndTarget, 0, SystemAllocPolicy> CallSiteAndTargetVector;
 
 // Summarizes a heap access made by wasm code that needs to be patched later
 // and/or looked up by the wasm signal handlers. Different architectures need
 // to know different things (x64: offset and length, ARM: where to patch in
 // heap length, x86: where to patch in heap length and base).
 
 #if defined(JS_CODEGEN_X86)
@@ -634,25 +649,17 @@ class HeapAccess
 #elif defined(JS_CODEGEN_NONE)
 class HeapAccess {
   public:
     void offsetInsnOffsetBy(uint32_t) { MOZ_CRASH(); }
     uint32_t insnOffset() const { MOZ_CRASH(); }
 };
 #endif
 
-} // namespace wasm
-} // namespace js
-namespace mozilla {
-template <> struct IsPod<js::wasm::HeapAccess> : TrueType {};
-}
-namespace js {
-namespace wasm {
-
-typedef Vector<HeapAccess, 0, SystemAllocPolicy> HeapAccessVector;
+WASM_DECLARE_POD_VECTOR(HeapAccess, HeapAccessVector)
 
 // A wasm::SymbolicAddress represents a pointer to a well-known function or
 // object that is embedded in wasm code. Since wasm code is serialized and
 // later deserialized into a different address space, symbolic addresses must be
 // used for *all* pointers into the address space. The MacroAssembler records a
 // list of all SymbolicAddresses and the offsets of their use in the code for
 // later patching during static linking.