1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jit_CacheIRHealth_h
8 #define jit_CacheIRHealth_h
10 #ifdef JS_CACHEIR_SPEW
12 # include "mozilla/Sprintf.h"
14 # include "NamespaceImports.h"
16 # include "jit/CacheIR.h"
17 # include "js/TypeDecls.h"
19 enum class JSOp
: uint8_t;
23 class AutoStructuredSpewer
;
32 // [SMDOC] CacheIR Health Report
34 // The goal of CacheIR health report is to make the costlier
35 // CacheIR stubs more apparent and easier to diagnose.
36 // This is done by using the scores assigned to different CacheIROps in
37 // CacheIROps.yaml (see the description of cost_estimate in the
38 // aforementioned file for how these scores are determined), summing
39 // the score of each op generated for a particular stub together, and displaying
40 // this score for each stub in an inline cache. The higher the total stub score,
41 // the more expensive the stub is.
43 // There are a few ways to generate a health report for a script:
44 // 1. Simply running a JS program with the evironment variable
45 // SPEW=CacheIRHealthReport. We generate a health report for a script
46 // whenever we reach the trial inlining threshold.
47 // ex) SPEW=CacheIRHealthReport dist/bin/js jsprogram.js
48 // 2. In the shell you can call cacheIRHealthReport() with no arguments and a
50 // will be generated for all scripts in the current zone.
51 // ex) cacheIRHealthReport()
52 // 3. You may also call cacheIRHealthReport() on a particular function to see
54 // health report associated with that function's script.
55 // ex) cacheIRHealthReport(foo)
57 // Once you have generated a health report, you may go to
58 // https://mozilla-spidermonkey.github.io/cacheirhealthreport/ to visualize the
59 // data and aid in understanding what may be going wrong with the CacheIR for a
60 // particular stub. For more information about the tool and why a particular
61 // script, inline cache entry, or stub is unhappy go to:
62 // https://mozilla-spidermonkey.github.io/cacheirhealthreport/info.html
64 enum SpewContext
: uint8_t { Shell
, Transition
, TrialInlining
};
67 enum Happiness
: uint8_t { Sad
, MediumSad
, MediumHappy
, Happy
};
69 // Get happiness from health score.
70 Happiness
determineStubHappiness(uint32_t stubHealthScore
);
71 // Health of an individual stub.
72 Happiness
spewStubHealth(AutoStructuredSpewer
& spew
, ICCacheIRStub
* stub
);
73 // If there is more than just a fallback stub in an IC Entry, then additional
74 // information about the IC entry.
75 bool spewNonFallbackICInformation(AutoStructuredSpewer
& spew
, JSContext
* cx
,
77 Happiness
* entryHappiness
);
78 // Health of all the stubs in an individual CacheIR Entry.
79 bool spewICEntryHealth(AutoStructuredSpewer
& spew
, JSContext
* cx
,
80 HandleScript script
, ICEntry
* entry
,
81 ICFallbackStub
* fallback
, jsbytecode
* pc
, JSOp op
,
82 Happiness
* entryHappiness
);
83 // Spews first and last property name for each shape checked by
84 // GuardShape in the stub.
85 void spewShapeInformation(AutoStructuredSpewer
& spew
, JSContext
* cx
,
87 // Returns the BaseScript of a Shape if available.
88 BaseScript
* maybeExtractBaseScript(JSContext
* cx
, Shape
* shape
);
91 // Spews the final hit count for scripts where we care about its final hit
93 void spewScriptFinalWarmUpCount(JSContext
* cx
, const char* filename
,
94 JSScript
* script
, uint32_t warmUpCount
);
95 // Spew the health of a particular ICEntry only.
96 void healthReportForIC(JSContext
* cx
, ICEntry
* entry
,
97 ICFallbackStub
* fallback
, HandleScript script
,
99 // If a JitScript exists, spew the health of all ICEntries that exist
100 // for the specified script.
101 void healthReportForScript(JSContext
* cx
, HandleScript script
,
102 SpewContext context
);
108 #endif /* JS_CACHEIR_SPEW */
109 #endif /* jit_CacheIRHealth_h */