Bug 968296 - IonMonkey: Snapshot's constant pool should reuse index of identical values. r=nbp
authorRomain Perier <romain.perier@gmail.com>
Sun, 02 Mar 2014 18:34:48 +0100
changeset 172349 0a0fcc54e630f0b7e1050b660cbe0d86126bc542
parent 172348 9a5b7ed8dae47207f8871d8330215e4c43bee86f
child 172350 57f1327fac32df05c23864ae46dc19d140bf0b34
push id26358
push usercbook@mozilla.com
push dateFri, 07 Mar 2014 11:48:31 +0000
treeherdermozilla-central@b9fc2eb18bd1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs968296
milestone30.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 968296 - IonMonkey: Snapshot's constant pool should reuse index of identical values. r=nbp
js/src/jit/Ion.cpp
js/src/jit/LIR.cpp
js/src/jit/LIR.h
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -1399,17 +1399,17 @@ OptimizeMIR(MIRGenerator *mir)
 }
 
 LIRGraph *
 GenerateLIR(MIRGenerator *mir)
 {
     MIRGraph &graph = mir->graph();
 
     LIRGraph *lir = mir->alloc().lifoAlloc()->new_<LIRGraph>(&graph);
-    if (!lir)
+    if (!lir || !lir->init())
         return nullptr;
 
     LIRGenerator lirgen(mir, graph, *lir);
     if (!lirgen.generate())
         return nullptr;
     IonSpewPass("Generate LIR");
 
     if (mir->shouldCancel("Generate LIR"))
--- a/js/src/jit/LIR.cpp
+++ b/js/src/jit/LIR.cpp
@@ -15,33 +15,41 @@
 #include "jit/MIRGenerator.h"
 
 using namespace js;
 using namespace js::jit;
 
 LIRGraph::LIRGraph(MIRGraph *mir)
   : blocks_(mir->alloc()),
     constantPool_(mir->alloc()),
+    constantPoolMap_(mir->alloc()),
     safepoints_(mir->alloc()),
     nonCallSafepoints_(mir->alloc()),
     numVirtualRegisters_(0),
     numInstructions_(1), // First id is 1.
     localSlotCount_(0),
     argumentSlotCount_(0),
     entrySnapshot_(nullptr),
     osrBlock_(nullptr),
     mir_(*mir)
 {
 }
 
 bool
 LIRGraph::addConstantToPool(const Value &v, uint32_t *index)
 {
+    JS_ASSERT(constantPoolMap_.initialized());
+
+    ConstantPoolMap::AddPtr p = constantPoolMap_.lookupForAdd(v);
+    if (p) {
+        *index = p->value();
+        return true;
+    }
     *index = constantPool_.length();
-    return constantPool_.append(v);
+    return constantPool_.append(v) && constantPoolMap_.add(p, v, *index);
 }
 
 bool
 LIRGraph::noteNeedsSafepoint(LInstruction *ins)
 {
     // Instructions with safepoints must be in linear order.
     JS_ASSERT_IF(!safepoints_.empty(), safepoints_.back()->id() < ins->id());
     if (!ins->isCall() && !nonCallSafepoints_.append(ins))
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -1364,18 +1364,32 @@ public:
 
     LAllocation *operator ->() const {
         return **this;
     }
 };
 
 class LIRGraph
 {
+    struct ValueHasher
+    {
+        typedef Value Lookup;
+        static HashNumber hash(const Value &v) {
+            return HashNumber(v.asRawBits());
+        }
+        static bool match(const Value &lhs, const Value &rhs) {
+            return lhs == rhs;
+        }
+    };
+
+
     Vector<LBlock *, 16, IonAllocPolicy> blocks_;
     Vector<Value, 0, IonAllocPolicy> constantPool_;
+    typedef HashMap<Value, uint32_t, ValueHasher, IonAllocPolicy> ConstantPoolMap;
+    ConstantPoolMap constantPoolMap_;
     Vector<LInstruction *, 0, IonAllocPolicy> safepoints_;
     Vector<LInstruction *, 0, IonAllocPolicy> nonCallSafepoints_;
     uint32_t numVirtualRegisters_;
     uint32_t numInstructions_;
 
     // Number of stack slots needed for local spills.
     uint32_t localSlotCount_;
     // Number of stack slots needed for argument construction for calls.
@@ -1387,16 +1401,19 @@ class LIRGraph
     // LBlock containing LOsrEntry, or nullptr.
     LBlock *osrBlock_;
 
     MIRGraph &mir_;
 
   public:
     LIRGraph(MIRGraph *mir);
 
+    bool init() {
+        return constantPoolMap_.init();
+    }
     MIRGraph &mir() const {
         return mir_;
     }
     size_t numBlocks() const {
         return blocks_.length();
     }
     LBlock *getBlock(size_t i) const {
         return blocks_[i];
@@ -1455,19 +1472,16 @@ class LIRGraph
     }
     bool addConstantToPool(const Value &v, uint32_t *index);
     size_t numConstants() const {
         return constantPool_.length();
     }
     Value *constantPool() {
         return &constantPool_[0];
     }
-    const Value &getConstant(size_t index) const {
-        return constantPool_[index];
-    }
     void setEntrySnapshot(LSnapshot *snapshot) {
         JS_ASSERT(!entrySnapshot_);
         JS_ASSERT(snapshot->bailoutKind() == Bailout_Normal);
         snapshot->setBailoutKind(Bailout_ArgumentCheck);
         entrySnapshot_ = snapshot;
     }
     LSnapshot *entrySnapshot() const {
         JS_ASSERT(entrySnapshot_);