| <link rel="import" href="../../../../packages/polymer/polymer.html"> |
| <link rel="import" href="code_ref.html"> |
| <link rel="import" href="function_ref.html"> |
| <link rel="import" href="nav_bar.html"> |
| <link rel="import" href="observatory_element.html"> |
| <link rel="import" href="sliding_checkbox.html"> |
| |
| <polymer-element name="cpu-profile" extends="observatory-element"> |
| <template> |
| <link rel="stylesheet" href="css/shared.css"> |
| <nav-bar> |
| <top-nav-menu></top-nav-menu> |
| <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu> |
| <nav-menu link="{{ makeLink('/profiler', isolate) }}" anchor="cpu profile" last="{{ true }}"></nav-menu> |
| <nav-refresh callback="{{ refresh }}"></nav-refresh> |
| <nav-refresh callback="{{ clear }}" label="Clear"></nav-refresh> |
| <nav-control></nav-control> |
| </nav-bar> |
| <style> |
| .tableWell { |
| background-color: #ECECEC; |
| padding: 0.2em; |
| } |
| |
| .table { |
| border-spacing: 0px; |
| width: 100%; |
| margin-bottom: 20px |
| vertical-align: middle; |
| } |
| |
| tr { |
| background-color: #FFFFFF; |
| } |
| |
| tbody tr { |
| animation: fadeIn 0.5s; |
| -moz-animation: fadeIn 0.5s; |
| -webkit-animation: fadeIn 0.5s; |
| } |
| |
| tbody tr:hover { |
| background-color: #FAFAFA; |
| } |
| |
| tr td:first-child, |
| tr th:first-child { |
| width: 100%; |
| } |
| |
| .table thead > tr > th { |
| padding: 8px; |
| vertical-align: bottom; |
| text-align: left; |
| border-bottom: 1px solid #ddd; |
| } |
| |
| .infoBox { |
| position: absolute; |
| top: 100%; |
| left: 0%; |
| z-index: 999; |
| opacity: 1; |
| padding: 1em; |
| background-color: #ffffff; |
| border-left: solid 2px #ECECEC; |
| border-bottom: solid 2px #ECECEC; |
| border-right: solid 2px #ECECEC; |
| } |
| |
| .statusMessage { |
| font-size: 150%; |
| font-weight: bold; |
| } |
| |
| .statusBox { |
| height: 100%; |
| padding: 1em; |
| } |
| |
| .center { |
| align-items: center; |
| justify-content: center; |
| } |
| |
| .notice { |
| background-color: #fcf8e3; |
| } |
| |
| .red { |
| background-color: #f2dede; |
| } |
| |
| </style> |
| <div class="content-centered-big"> |
| <h1>Sampled CPU profile</h1> |
| <hr> |
| <template if="{{ state == 'Requested' }}"> |
| <div class="statusBox shadow center"> |
| <div class="statusMessage">Fetching profile from VM...</div> |
| </div> |
| </template> |
| <template if="{{ state == 'Loading' }}"> |
| <div class="statusBox shadow center"> |
| <div class="statusMessage">Loading profile...</div> |
| </div> |
| </template> |
| <template if="{{ state == 'Exception' }}"> |
| <div class="statusBox shadow center"> |
| <div class="statusMessage"> |
| <h1>Exception:</h1> |
| <br> |
| <pre>{{ exception.toString() }}</pre> |
| <br> |
| <h1>Stack trace:</h1> |
| <br> |
| <pre>{{ stackTrace.toString() }}</pre> |
| </div> |
| </div> |
| </template> |
| <template if="{{ state == 'Loaded' }}"> |
| <div class="memberList"> |
| <div class="memberItem"> |
| <div class="memberName">Refreshed at </div> |
| <div class="memberValue">{{ refreshTime }} (fetched in {{ fetchTime }}) (loaded in {{ loadTime }})</div> |
| </div> |
| <div class="memberItem"> |
| <div class="memberName">Profile contains</div> |
| <div class="memberValue">{{ sampleCount }} samples (spanning {{ timeSpan }})</div> |
| </div> |
| <div class="memberItem"> |
| <div class="memberName">Sampling</div> |
| <div class="memberValue">{{ stackDepth }} stack frames @ {{ sampleRate }} Hz</div> |
| </div> |
| <div class="memberItem"> |
| <div class="memberName">Mode</div> |
| <div class="memberValue"> |
| <select value="{{modeSelector}}"> |
| <option value="Code">Code</option> |
| <option value="Function">Function</option> |
| </select> |
| </div> |
| </div> |
| <div class="memberItem"> |
| <div class="memberName">Tag Order</div> |
| <div class="memberValue"> |
| <select value="{{tagSelector}}"> |
| <option value="UserVM">User > VM</option> |
| <option value="UserOnly">User</option> |
| <option value="VMUser">VM > User</option> |
| <option value="VMOnly">VM</option> |
| <option value="None">None</option> |
| </select> |
| </div> |
| </div> |
| <!--- Experimental |
| <div class="memberItem"> |
| <div class="memberName">Call Tree Direction</div> |
| <div class="memberValue"> |
| <select value="{{directionSelector}}"> |
| <option value="Down">Top down</option> |
| <option value="Up">Bottom up</option> |
| </select> |
| </div> |
| </div> |
| ---> |
| </div> |
| </template> |
| <template if="{{ state == 'Loaded' && directionSelector == 'Down' }}"> |
| <br> |
| <div class="statusBox shadow"> |
| <div>Tree is rooted at main.</div> |
| <br> |
| <div>Child nodes are callees.</div> |
| <br> |
| <div class="notice">To get the most out of this mode you may need to launch Dart with a higher --profile-depth flag value.</div> |
| <div class="notice">Try 16, 32, ... up to 256 until [Truncated] approaches zero.</div> |
| <div class="red">NOTE: Higher values will impact performance</div> |
| </div> |
| </template> |
| <template if="{{ state == 'Loaded' && directionSelector == 'Up' }}"> |
| <br> |
| <div class="statusBox shadow"> |
| <div>Tree is rooted at executing function / code.</div> |
| <br> |
| <div>Child nodes are callers.</div> |
| </div> |
| </template> |
| <br><br> |
| <div class="tableWell shadow"> |
| <table class="table"> |
| <thead id="treeHeader"> |
| <tr> |
| <th>Method</th> |
| <th>Self</th> |
| </tr> |
| </thead> |
| <tbody id="treeBody"> |
| </tbody> |
| </table> |
| </div> |
| </div> |
| </template> |
| </polymer-element> |
| |
| <script type="application/dart" src="cpu_profile.dart"></script> |