Bug 1027441 - OdinMonkey: Fix use of size() with pending pool entries. r=luke, a=sledru
authorDouglas Crosher <dtc-moz@scieneer.com>
Mon, 23 Jun 2014 14:20:51 +1000
changeset 208326 8b1e5cf98def02b734f5f9bbbbe720faa8bd795c
parent 208325 1a06329ebf36380961e4966852d6f1d6be90cd63
child 208327 67ae33e96d945d23c972322b67233b2123014f92
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke, sledru
bugs1027441
milestone32.0a2
Bug 1027441 - OdinMonkey: Fix use of size() with pending pool entries. r=luke, a=sledru
js/src/jit/AsmJS.cpp
js/src/jit/AsmJSModule.h
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -1449,36 +1449,27 @@ class MOZ_STACK_CLASS ModuleCompiler
     bool addFunctionCounts(IonScriptCounts *counts) {
         return module_->addFunctionCounts(counts);
     }
 
     void finishFunctionBodies() {
         JS_ASSERT(!finishedFunctionBodies_);
         masm_.align(AsmJSPageSize);
         finishedFunctionBodies_ = true;
-        module_->initFunctionBytes(masm_.size());
+        module_->initFunctionBytes(masm_.currentOffset());
     }
 
     void setInterpExitOffset(unsigned exitIndex) {
-#if defined(JS_CODEGEN_ARM)
-        masm_.flush();
-#endif
-        module_->exit(exitIndex).initInterpOffset(masm_.size());
+        module_->exit(exitIndex).initInterpOffset(masm_.currentOffset());
     }
     void setIonExitOffset(unsigned exitIndex) {
-#if defined(JS_CODEGEN_ARM)
-        masm_.flush();
-#endif
-        module_->exit(exitIndex).initIonOffset(masm_.size());
+        module_->exit(exitIndex).initIonOffset(masm_.currentOffset());
     }
     void setEntryOffset(unsigned exportIndex) {
-#if defined(JS_CODEGEN_ARM)
-        masm_.flush();
-#endif
-        module_->exportedFunction(exportIndex).initCodeOffset(masm_.size());
+        module_->exportedFunction(exportIndex).initCodeOffset(masm_.currentOffset());
     }
 
     void buildCompilationTimeReport(bool storedInCache, ScopedJSFreePtr<char> *out) {
         ScopedJSFreePtr<char> slowFuns;
 #ifndef JS_MORE_DETERMINISTIC
         int64_t usecAfter = PRMJ_Now();
         int msTotal = (usecAfter - usecBefore_) / PRMJ_USEC_PER_MSEC;
         if (!slowFunctions_.empty()) {
@@ -1517,47 +1508,52 @@ class MOZ_STACK_CLASS ModuleCompiler
 
 #if defined(JS_CODEGEN_ARM)
         // Now that compilation has finished, we need to update offsets to
         // reflect actual offsets (an ARM distinction).
         for (unsigned i = 0; i < module_->numHeapAccesses(); i++) {
             AsmJSHeapAccess &a = module_->heapAccess(i);
             a.setOffset(masm_.actualOffset(a.offset()));
         }
+        for (unsigned i = 0; i < module_->numExportedFunctions(); i++)
+            module_->exportedFunction(i).updateCodeOffset(masm_);
+        for (unsigned i = 0; i < module_->numExits(); i++)
+            module_->exit(i).updateOffsets(masm_);
         for (unsigned i = 0; i < module_->numCallSites(); i++) {
             CallSite &c = module_->callSite(i);
             c.setReturnAddressOffset(masm_.actualOffset(c.returnAddressOffset()));
         }
 #endif
 
         // The returned memory is owned by module_.
         if (!module_->allocateAndCopyCode(cx_, masm_))
             return false;
 
+        module_->updateFunctionBytes(masm_);
         // c.f. JitCode::copyFrom
         JS_ASSERT(masm_.jumpRelocationTableBytes() == 0);
         JS_ASSERT(masm_.dataRelocationTableBytes() == 0);
         JS_ASSERT(masm_.preBarrierTableBytes() == 0);
         JS_ASSERT(!masm_.hasEnteredExitFrame());
 
 #if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
-        // Fix up the code offsets.  Note the endCodeOffset should not be
-        // filtered through 'actualOffset' as it is generated using 'size()'
-        // rather than a label.
+        // Fix up the code offsets.
         for (unsigned i = 0; i < module_->numProfiledFunctions(); i++) {
             AsmJSModule::ProfiledFunction &func = module_->profiledFunction(i);
             func.pod.startCodeOffset = masm_.actualOffset(func.pod.startCodeOffset);
+            func.pod.endCodeOffset = masm_.actualOffset(func.pod.endCodeOffset);
         }
 #endif
 
 #ifdef JS_ION_PERF
         for (unsigned i = 0; i < module_->numPerfBlocksFunctions(); i++) {
             AsmJSModule::ProfiledBlocksFunction &func = module_->perfProfiledBlocksFunction(i);
             func.pod.startCodeOffset = masm_.actualOffset(func.pod.startCodeOffset);
             func.endInlineCodeOffset = masm_.actualOffset(func.endInlineCodeOffset);
+            func.pod.endCodeOffset = masm_.actualOffset(func.pod.endCodeOffset);
             BasicBlocksVector &basicBlocks = func.blocks;
             for (uint32_t i = 0; i < basicBlocks.length(); i++) {
                 Record &r = basicBlocks[i];
                 r.startOffset = masm_.actualOffset(r.startOffset);
                 r.endOffset = masm_.actualOffset(r.endOffset);
             }
         }
 #endif
@@ -5511,25 +5507,25 @@ GenerateCode(ModuleCompiler &m, ModuleCo
         return false;
     }
 
 #if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
     // Profiling might not be active now, but it may be activated later (perhaps
     // after the module has been cached and reloaded from the cache). Function
     // profiling info isn't huge, so store it always (in --enable-profiling
     // builds, which is only Nightly builds, but default).
-    if (!m.trackProfiledFunction(func, m.masm().size()))
+    if (!m.trackProfiledFunction(func, m.masm().currentOffset()))
         return false;
 #endif
 
 #ifdef JS_ION_PERF
     // Per-block profiling info uses significantly more memory so only store
     // this information if it is actively requested.
     if (PerfBlockEnabled()) {
-        if (!m.trackPerfProfiledBlocks(mir.perfSpewer(), func, m.masm().size()))
+        if (!m.trackPerfProfiledBlocks(mir.perfSpewer(), func, m.masm().currentOffset()))
             return false;
     }
 #endif
 
     // Align internal function headers.
     m.masm().align(CodeAlignment);
 
     func.accumulateCompileTime((PRMJ_Now() - before) / PRMJ_USEC_PER_MSEC);
--- a/js/src/jit/AsmJSModule.h
+++ b/js/src/jit/AsmJSModule.h
@@ -196,16 +196,20 @@ class AsmJSModule
         void initInterpOffset(unsigned off) {
             JS_ASSERT(!interpCodeOffset_);
             interpCodeOffset_ = off;
         }
         void initIonOffset(unsigned off) {
             JS_ASSERT(!ionCodeOffset_);
             ionCodeOffset_ = off;
         }
+        void updateOffsets(jit::MacroAssembler &masm) {
+            interpCodeOffset_ = masm.actualOffset(interpCodeOffset_);
+            ionCodeOffset_ = masm.actualOffset(ionCodeOffset_);
+        }
 
         size_t serializedSize() const;
         uint8_t *serialize(uint8_t *cursor) const;
         const uint8_t *deserialize(ExclusiveContext *cx, const uint8_t *cursor);
         bool clone(ExclusiveContext *cx, Exit *out) const;
     };
     typedef int32_t (*CodePtr)(uint64_t *args, uint8_t *global);
 
@@ -255,16 +259,19 @@ class AsmJSModule
       public:
         ExportedFunction() {}
         ExportedFunction(ExportedFunction &&rhs) {
             name_ = rhs.name_;
             maybeFieldName_ = rhs.maybeFieldName_;
             argCoercions_ = mozilla::Move(rhs.argCoercions_);
             pod = rhs.pod;
         }
+        void updateCodeOffset(jit::MacroAssembler &masm) {
+            pod.codeOffset_ = masm.actualOffset(pod.codeOffset_);
+        }
 
         void initCodeOffset(unsigned off) {
             JS_ASSERT(pod.codeOffset_ == UINT32_MAX);
             pod.codeOffset_ = off;
         }
 
         PropertyName *name() const {
             return name_;
@@ -800,19 +807,22 @@ class AsmJSModule
         return exits_[exitIndex].globalDataOffset();
     }
     ExitDatum &exitIndexToGlobalDatum(unsigned exitIndex) const {
         return *(ExitDatum *)(globalData() + exitIndexToGlobalDataOffset(exitIndex));
     }
 
     void initFunctionBytes(size_t functionBytes) {
         JS_ASSERT(pod.functionBytes_ == 0);
-        JS_ASSERT(functionBytes % AsmJSPageSize == 0);
         pod.functionBytes_ = functionBytes;
     }
+    void updateFunctionBytes(jit::MacroAssembler &masm) {
+        pod.functionBytes_ = masm.actualOffset(pod.functionBytes_);
+        JS_ASSERT(pod.functionBytes_ % AsmJSPageSize == 0);
+    }
     size_t functionBytes() const {
         JS_ASSERT(pod.functionBytes_);
         JS_ASSERT(pod.functionBytes_ % AsmJSPageSize == 0);
         return pod.functionBytes_;
     }
     bool containsPC(void *pc) const {
         return pc >= code_ && pc < (code_ + functionBytes());
     }