Bug 891437 - Implement mozilla/Array.h, a class suitable for use where a C array would be used, with additional debug bounds-checking. r=Ms2ger
authorJeff Walden <jwalden@mit.edu>
Thu, 07 Feb 2013 15:32:20 -0800
changeset 138693 31aa18b9b25073aa2a6b82d3f95a54821e81cdb3
parent 138692 5a4b367aae64db4e6cdaabcf87d4b6c301bb5f3c
child 138694 cc877a2930f82b50bcc5b6dfa0d29c37b5826af8
push id24964
push userryanvm@gmail.com
push dateTue, 16 Jul 2013 20:04:09 +0000
treeherderautoland@fd10ead17ace [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMs2ger
bugs891437
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 891437 - Implement mozilla/Array.h, a class suitable for use where a C array would be used, with additional debug bounds-checking. r=Ms2ger
js/src/ion/AliasAnalysis.cpp
js/src/ion/BacktrackingAllocator.h
js/src/ion/FixedArityList.h
js/src/ion/LIR.h
js/src/ion/LiveRangeAllocator.h
js/src/ion/MIR.h
js/src/ion/Registers.h
mfbt/Array.h
mfbt/exported_headers.mk
--- a/js/src/ion/AliasAnalysis.cpp
+++ b/js/src/ion/AliasAnalysis.cpp
@@ -11,16 +11,18 @@
 #include "ion/MIRGraph.h"
 #include "ion/Ion.h"
 #include "ion/IonBuilder.h"
 #include "ion/IonSpewer.h"
 
 using namespace js;
 using namespace js::ion;
 
+using mozilla::Array;
+
 // Iterates over the flags in an AliasSet.
 class AliasSetIterator
 {
   private:
     uint32_t flags;
     unsigned pos;
 
   public:
@@ -112,17 +114,17 @@ IonSpewAliasInfo(const char *pre, MDefin
 // having an implicit dependency on the last instruction of the loop header, so that
 // it's never moved before the loop header.
 //
 // The algorithm depends on the invariant that both control instructions and effectful
 // instructions (stores) are never hoisted.
 bool
 AliasAnalysis::analyze()
 {
-    FixedArityList<MDefinitionVector, AliasSet::NumCategories> stores;
+    Array<MDefinitionVector, AliasSet::NumCategories> stores;
 
     // Initialize to the first instruction.
     MDefinition *firstIns = *graph_.begin()->begin();
     for (unsigned i=0; i < AliasSet::NumCategories; i++) {
         if (!stores[i].append(firstIns))
             return false;
     }
 
--- a/js/src/ion/BacktrackingAllocator.h
+++ b/js/src/ion/BacktrackingAllocator.h
@@ -2,16 +2,18 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ion_BacktrackingAllocator_h
 #define ion_BacktrackingAllocator_h
 
+#include "mozilla/Array.h"
+
 #include "ion/LiveRangeAllocator.h"
 
 #include "ds/PriorityQueue.h"
 #include "ds/SplayTree.h"
 
 // Backtracking priority queue based register allocator based on that described
 // in the following blog post:
 //
@@ -155,17 +157,17 @@ class BacktrackingAllocator : public Liv
     // that register is currently allocated.
     struct PhysicalRegister {
         bool allocatable;
         AnyRegister reg;
         AllocatedRangeSet allocations;
 
         PhysicalRegister() : allocatable(false) {}
     };
-    FixedArityList<PhysicalRegister, AnyRegister::Total> registers;
+    mozilla::Array<PhysicalRegister, AnyRegister::Total> registers;
 
     // Ranges of code which are considered to be hot, for which good allocation
     // should be prioritized.
     AllocatedRangeSet hotcode;
 
   public:
     BacktrackingAllocator(MIRGenerator *mir, LIRGenerator *lir, LIRGraph &graph)
       : LiveRangeAllocator<BacktrackingVirtualRegister>(mir, lir, graph, /* forLSRA = */ false)
deleted file mode 100644
--- a/js/src/ion/FixedArityList.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef ion_FixedArityList_h
-#define ion_FixedArityList_h
-
-namespace js {
-namespace ion {
-
-template <typename T, size_t Arity>
-class FixedArityList
-{
-    T list_[Arity];
-
-  public:
-    FixedArityList()
-      : list_()
-    { }
-
-    T &operator [](size_t index) {
-        JS_ASSERT(index < Arity);
-        return list_[index];
-    }
-    const T &operator [](size_t index) const {
-        JS_ASSERT(index < Arity);
-        return list_[index];
-    }
-};
-
-template <typename T>
-class FixedArityList<T, 0>
-{
-  public:
-    T &operator [](size_t index) {
-        MOZ_ASSUME_UNREACHABLE("no items");
-    }
-    const T &operator [](size_t index) const {
-        MOZ_ASSUME_UNREACHABLE("no items");
-    }
-};
-
-} // namespace ion
-} // namespace js
-
-#endif /* ion_FixedArityList_h */
--- a/js/src/ion/LIR.h
+++ b/js/src/ion/LIR.h
@@ -5,20 +5,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ion_LIR_h
 #define ion_LIR_h
 
 // This file declares the core data structures for LIR: storage allocations for
 // inputs and outputs, as well as the interface instructions must conform to.
 
+#include "mozilla/Array.h"
+
 #include "jscntxt.h"
+
 #include "ion/IonAllocPolicy.h"
 #include "ion/InlineList.h"
-#include "ion/FixedArityList.h"
 #include "ion/LOpcodes.h"
 #include "ion/Registers.h"
 #include "ion/MIR.h"
 #include "ion/MIRGraph.h"
 #include "ion/shared/Assembler-shared.h"
 #include "ion/Safepoints.h"
 #include "ion/Bailouts.h"
 #include "ion/VMFunctions.h"
@@ -800,19 +802,19 @@ class LBlock : public TempObject
     Label *label();
     LMoveGroup *getEntryMoveGroup();
     LMoveGroup *getExitMoveGroup();
 };
 
 template <size_t Defs, size_t Operands, size_t Temps>
 class LInstructionHelper : public LInstruction
 {
-    FixedArityList<LDefinition, Defs> defs_;
-    FixedArityList<LAllocation, Operands> operands_;
-    FixedArityList<LDefinition, Temps> temps_;
+    mozilla::Array<LDefinition, Defs> defs_;
+    mozilla::Array<LAllocation, Operands> operands_;
+    mozilla::Array<LDefinition, Temps> temps_;
 
   public:
     size_t numDefs() const MOZ_FINAL MOZ_OVERRIDE {
         return Defs;
     }
     LDefinition *getDef(size_t index) MOZ_FINAL MOZ_OVERRIDE {
         return &defs_[index];
     }
--- a/js/src/ion/LiveRangeAllocator.h
+++ b/js/src/ion/LiveRangeAllocator.h
@@ -2,16 +2,17 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ion_LiveRangeAllocator_h
 #define ion_LiveRangeAllocator_h
 
+#include "mozilla/Array.h"
 #include "mozilla/DebugOnly.h"
 
 #include "ion/RegisterAllocator.h"
 #include "ion/StackSlotAllocator.h"
 
 // Common structures and functions used by register allocators that operate on
 // virtual register live ranges.
 
@@ -517,17 +518,17 @@ typedef InlineList<LiveInterval>::revers
 
 template <typename VREG>
 class LiveRangeAllocator : public RegisterAllocator
 {
   protected:
     // Computed inforamtion
     BitSet **liveIn;
     VirtualRegisterMap<VREG> vregs;
-    FixedArityList<LiveInterval *, AnyRegister::Total> fixedIntervals;
+    mozilla::Array<LiveInterval *, AnyRegister::Total> fixedIntervals;
 
     // Union of all ranges in fixedIntervals, used to quickly determine
     // whether an interval intersects with a fixed register.
     LiveInterval *fixedIntervalsUnion;
 
     // Whether the underlying allocator is LSRA. This changes the generated
     // live ranges in various ways: inserting additional fixed uses of
     // registers, and shifting the boundaries of live ranges by small amounts.
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -1,28 +1,32 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/*
+ * Everything needed to build actual MIR instructions: the actual opcodes and
+ * instructions, the instruction interface, and use chains.
+ */
+
 #ifndef ion_MIR_h
 #define ion_MIR_h
 
-// This file declares everything needed to build actual MIR instructions: the
-// actual opcodes and instructions themselves, the instruction interface, and
-// use chains.
+#include "mozilla/Array.h"
+
 #include "jscntxt.h"
+#include "jsinfer.h"
 #include "jslibmath.h"
-#include "jsinfer.h"
+
 #include "ion/TypePolicy.h"
 #include "ion/IonAllocPolicy.h"
 #include "ion/InlineList.h"
 #include "ion/MOpcodes.h"
-#include "ion/FixedArityList.h"
 #include "ion/IonMacroAssembler.h"
 #include "ion/Bailouts.h"
 #include "ion/FixedList.h"
 #include "ion/CompilerRoot.h"
 #include "vm/ScopeObject.h"
 
 namespace js {
 
@@ -621,17 +625,17 @@ class MInstruction
     bool accept(MInstructionVisitor *visitor) {                             \
         return visitor->visit##opcode(this);                                \
     }
 
 template <size_t Arity>
 class MAryInstruction : public MInstruction
 {
   protected:
-    FixedArityList<MUse, Arity> operands_;
+    mozilla::Array<MUse, Arity> operands_;
 
     void setOperand(size_t index, MDefinition *operand) MOZ_FINAL MOZ_OVERRIDE {
         operands_[index].set(operand, this, index);
         operand->addUse(&operands_[index]);
     }
 
     MUse *getUseFor(size_t index) MOZ_FINAL MOZ_OVERRIDE {
         return &operands_[index];
@@ -938,18 +942,18 @@ class MTableSwitch MOZ_FINAL
     size_t numOperands() const {
         return 1;
     }
 };
 
 template <size_t Arity, size_t Successors>
 class MAryControlInstruction : public MControlInstruction
 {
-    FixedArityList<MUse, Arity> operands_;
-    FixedArityList<MBasicBlock *, Successors> successors_;
+    mozilla::Array<MUse, Arity> operands_;
+    mozilla::Array<MBasicBlock *, Successors> successors_;
 
   protected:
     void setOperand(size_t index, MDefinition *operand) MOZ_FINAL MOZ_OVERRIDE {
         operands_[index].set(operand, this, index);
         operand->addUse(&operands_[index]);
     }
     void setSuccessor(size_t index, MBasicBlock *successor) {
         successors_[index] = successor;
--- a/js/src/ion/Registers.h
+++ b/js/src/ion/Registers.h
@@ -2,26 +2,27 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ion_Registers_h
 #define ion_Registers_h
 
+#include "mozilla/Array.h"
+
 #include "jsutil.h"
 #include "ion/IonTypes.h"
 #if defined(JS_CPU_X86)
 # include "ion/x86/Architecture-x86.h"
 #elif defined(JS_CPU_X64)
 # include "ion/x64/Architecture-x64.h"
 #elif defined(JS_CPU_ARM)
 # include "ion/arm/Architecture-arm.h"
 #endif
-#include "ion/FixedArityList.h"
 
 // ARM defines the RegisterID within Architecture-arm.h
 #if !defined(JS_CPU_ARM)
 #include "assembler/assembler/MacroAssembler.h"
 #endif
 
 namespace js {
 namespace ion {
@@ -82,18 +83,18 @@ struct FloatRegister {
     bool volatile_() const {
         return !!((1 << code()) & FloatRegisters::VolatileMask);
     }
 };
 
 // Information needed to recover machine register state.
 class MachineState
 {
-    FixedArityList<uintptr_t *, Registers::Total> regs_;
-    FixedArityList<double *, FloatRegisters::Total> fpregs_;
+    mozilla::Array<uintptr_t *, Registers::Total> regs_;
+    mozilla::Array<double *, FloatRegisters::Total> fpregs_;
 
   public:
     static MachineState FromBailout(uintptr_t regs[Registers::Total],
                                     double fpregs[FloatRegisters::Total]);
 
     void setRegisterLocation(Register reg, uintptr_t *up) {
         regs_[reg.code()] = up;
     }
new file mode 100644
--- /dev/null
+++ b/mfbt/Array.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* A compile-time constant-length array with bounds-checking assertions. */
+
+#ifndef mozilla_Array_h_
+#define mozilla_Array_h_
+
+#include "mozilla/Assertions.h"
+#include "mozilla/Attributes.h"
+
+#include <stddef.h>
+
+namespace mozilla {
+
+template<typename T, size_t Length>
+class Array
+{
+    T arr[Length];
+
+  public:
+    T& operator[](size_t i) {
+      MOZ_ASSERT(i < Length);
+      return arr[i];
+    }
+
+    const T& operator[](size_t i) const {
+      MOZ_ASSERT(i < Length);
+      return arr[i];
+    }
+};
+
+template<typename T>
+class Array<T, 0>
+{
+  public:
+    T& operator[](size_t i) {
+      MOZ_ASSUME_UNREACHABLE("indexing into zero-length array");
+    }
+
+    const T& operator[](size_t i) const {
+      MOZ_ASSUME_UNREACHABLE("indexing into zero-length array");
+    }
+};
+
+}  /* namespace mozilla */
+
+#endif /* mozilla_Array_h_ */
--- a/mfbt/exported_headers.mk
+++ b/mfbt/exported_headers.mk
@@ -5,16 +5,17 @@
 # This file defines the headers exported by mfbt.  It is included by mfbt
 # itself and by the JS engine, which, when built standalone, must install
 # mfbt's exported headers itself.
 
 EXPORTS_NAMESPACES += mozilla
 
 EXPORTS_mozilla += \
   AllocPolicy.h \
+  Array.h \
   Assertions.h \
   Atomics.h \
   Attributes.h \
   BloomFilter.h \
   Casting.h \
   Char16.h \
   CheckedInt.h \
   Compiler.h \