Bug 1448563 - Part 6: Add memory reporting for off-thread WASM. r=luke
authorTed Campbell <tcampbell@mozilla.com>
Wed, 11 Apr 2018 15:49:36 -0400
changeset 468733 9938026038b1d8e5884a61b8ab77ee9aff478ae1
parent 468732 22ae9a18a77564be0815ca494b979d84710ef15b
child 468734 63a48a0499b6e4ddd21c9ccfc6a3eeecc1a6b5c2
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1448563
milestone61.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 1448563 - Part 6: Add memory reporting for off-thread WASM. r=luke MozReview-Commit-ID: 1lXRj1JUJk2
js/public/MemoryMetrics.h
js/src/vm/HelperThreads.cpp
js/src/wasm/WasmGenerator.cpp
js/src/wasm/WasmGenerator.h
js/xpconnect/src/XPCJSRuntime.cpp
--- a/js/public/MemoryMetrics.h
+++ b/js/public/MemoryMetrics.h
@@ -504,17 +504,18 @@ struct NotableScriptSourceInfo : public 
     NotableScriptSourceInfo(const NotableScriptSourceInfo& info) = delete;
 };
 
 struct HelperThreadStats
 {
 #define FOR_EACH_SIZE(macro) \
     macro(_, MallocHeap, stateData) \
     macro(_, MallocHeap, parseTask) \
-    macro(_, MallocHeap, ionBuilder)
+    macro(_, MallocHeap, ionBuilder) \
+    macro(_, MallocHeap, wasmCompile)
 
     explicit HelperThreadStats()
       : FOR_EACH_SIZE(ZERO_SIZE)
         idleThreadCount(0),
         activeThreadCount(0)
     { }
 
     FOR_EACH_SIZE(DECL_SIZE)
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -18,16 +18,17 @@
 #include "threading/CpuCount.h"
 #include "util/NativeStack.h"
 #include "vm/Debugger.h"
 #include "vm/ErrorReporting.h"
 #include "vm/SharedImmutableStringsCache.h"
 #include "vm/Time.h"
 #include "vm/TraceLogging.h"
 #include "vm/Xdr.h"
+#include "wasm/WasmGenerator.h"
 
 #include "gc/PrivateIterators-inl.h"
 #include "vm/JSCompartment-inl.h"
 #include "vm/JSContext-inl.h"
 #include "vm/JSObject-inl.h"
 #include "vm/JSScript-inl.h"
 #include "vm/NativeObject-inl.h"
 
@@ -1171,16 +1172,22 @@ GlobalHelperThreadState::addSizeOfInclud
     // Report IonBuilders on wait lists
     for (auto builder : ionWorklist_)
         htStats.ionBuilder += builder->sizeOfIncludingThis(mallocSizeOf);
     for (auto builder : ionFinishedList_)
         htStats.ionBuilder += builder->sizeOfIncludingThis(mallocSizeOf);
     for (auto builder : ionFreeList_)
         htStats.ionBuilder += builder->sizeOfIncludingThis(mallocSizeOf);
 
+    // Report wasm::CompileTasks on wait lists
+    for (auto task : wasmWorklist_tier1_)
+        htStats.wasmCompile += task->sizeOfIncludingThis(mallocSizeOf);
+    for (auto task : wasmWorklist_tier2_)
+        htStats.wasmCompile += task->sizeOfIncludingThis(mallocSizeOf);
+
     // Report number of helper threads.
     MOZ_ASSERT(htStats.idleThreadCount == 0);
     if (threads) {
         for (auto& thread : *threads) {
             if (thread.idle())
                 htStats.idleThreadCount++;
             else
                 htStats.activeThreadCount++;
--- a/js/src/wasm/WasmGenerator.cpp
+++ b/js/src/wasm/WasmGenerator.cpp
@@ -1020,8 +1020,33 @@ ModuleGenerator::finishTier2(Module& mod
     if (MOZ_UNLIKELY(JitOptions.wasmDelayTier2)) {
         // Introduce an artificial delay when testing wasmDelayTier2, since we
         // want to exercise both tier1 and tier2 code in this case.
         std::this_thread::sleep_for(std::chrono::milliseconds(500));
     }
 
     return module.finishTier2(Move(linkDataTier_), Move(tier2), env_);
 }
+
+size_t
+CompiledCode::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
+{
+    size_t trapSitesSize = 0;
+    for (const TrapSiteVector& vec : trapSites)
+        trapSitesSize += vec.sizeOfExcludingThis(mallocSizeOf);
+
+    return bytes.sizeOfExcludingThis(mallocSizeOf) +
+           codeRanges.sizeOfExcludingThis(mallocSizeOf) +
+           callSites.sizeOfExcludingThis(mallocSizeOf) +
+           callSiteTargets.sizeOfExcludingThis(mallocSizeOf) +
+           trapSitesSize +
+           callFarJumps.sizeOfExcludingThis(mallocSizeOf) +
+           symbolicAccesses.sizeOfExcludingThis(mallocSizeOf) +
+           codeLabels.sizeOfExcludingThis(mallocSizeOf);
+}
+
+size_t
+CompileTask::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
+{
+    return lifo.sizeOfExcludingThis(mallocSizeOf) +
+           inputs.sizeOfExcludingThis(mallocSizeOf) +
+           output.sizeOfExcludingThis(mallocSizeOf);
+}
--- a/js/src/wasm/WasmGenerator.h
+++ b/js/src/wasm/WasmGenerator.h
@@ -14,16 +14,18 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #ifndef wasm_generator_h
 #define wasm_generator_h
 
+#include "mozilla/MemoryReporting.h"
+
 #include "jit/MacroAssembler.h"
 #include "wasm/WasmCompile.h"
 #include "wasm/WasmModule.h"
 #include "wasm/WasmValidate.h"
 
 namespace js {
 namespace wasm {
 
@@ -88,16 +90,18 @@ struct CompiledCode
                codeRanges.empty() &&
                callSites.empty() &&
                callSiteTargets.empty() &&
                trapSites.empty() &&
                callFarJumps.empty() &&
                symbolicAccesses.empty() &&
                codeLabels.empty();
     }
+
+    size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 };
 
 // The CompileTaskState of a ModuleGenerator contains the mutable state shared
 // between helper threads executing CompileTasks. Each CompileTask started on a
 // helper thread eventually either ends up in the 'finished' list or increments
 // 'numFailed'.
 
 struct CompileTaskState
@@ -123,16 +127,22 @@ struct CompileTask
     FuncCompileInputVector     inputs;
     CompiledCode               output;
 
     CompileTask(const ModuleEnvironment& env, ExclusiveCompileTaskState& state, size_t defaultChunkSize)
       : env(env),
         state(state),
         lifo(defaultChunkSize)
     {}
+
+    size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
+    size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
+    {
+        return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf);
+    }
 };
 
 // A ModuleGenerator encapsulates the creation of a wasm module. During the
 // lifetime of a ModuleGenerator, a sequence of FunctionGenerators are created
 // and destroyed to compile the individual function bodies. After generating all
 // functions, ModuleGenerator::finish() must be called to complete the
 // compilation and extract the resulting wasm module.
 
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -2494,16 +2494,20 @@ JSReporter::CollectReports(WindowPaths* 
 
     REPORT_BYTES(NS_LITERAL_CSTRING("explicit/js-non-window/helper-thread/parse-task"),
         KIND_HEAP, gStats.helperThread.parseTask,
         "The memory used by ParseTasks waiting in HelperThreadState.");
 
     REPORT_BYTES(NS_LITERAL_CSTRING("explicit/js-non-window/helper-thread/ion-builder"),
         KIND_HEAP, gStats.helperThread.ionBuilder,
         "The memory used by IonBuilders waiting in HelperThreadState.");
+
+    REPORT_BYTES(NS_LITERAL_CSTRING("explicit/js-non-window/helper-thread/wasm-compile"),
+        KIND_HEAP, gStats.helperThread.parseTask,
+        "The memory used by Wasm compilations waiting in HelperThreadState.");
 }
 
 static nsresult
 JSSizeOfTab(JSObject* objArg, size_t* jsObjectsSize, size_t* jsStringsSize,
             size_t* jsPrivateSize, size_t* jsOtherSize)
 {
     JSContext* cx = XPCJSContext::Get()->Context();
     JS::RootedObject obj(cx, objArg);