Index: runtime/observatory/lib/src/elements/cpu_profile.html |
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.html b/runtime/observatory/lib/src/elements/cpu_profile.html |
index 4893f99ef0d17b854800aac7bb222f918905439c..11d37b068bae87f335efd1db1a540b82f06a2461 100644 |
--- a/runtime/observatory/lib/src/elements/cpu_profile.html |
+++ b/runtime/observatory/lib/src/elements/cpu_profile.html |
@@ -5,6 +5,271 @@ |
<link rel="import" href="observatory_element.html"> |
<link rel="import" href="sliding_checkbox.html"> |
+<polymer-element name="cpu-profile-table" 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-table', isolate) }}" anchor="cpu profile (table)" last="{{ true }}"></nav-menu> |
+ <nav-refresh callback="{{ refresh }}"></nav-refresh> |
+ <nav-refresh callback="{{ clear }}" label="Clear"></nav-refresh> |
+ </nav-bar> |
+ <style> |
+ /* general */ |
+ .well { |
+ background-color: #ECECEC; |
+ padding: 0.2em; |
+ } |
+ .center { |
+ align-items: center; |
+ justify-content: center; |
+ } |
+ |
+ /* status messages */ |
+ .statusMessage { |
+ font-size: 150%; |
+ font-weight: bold; |
+ } |
+ .statusBox { |
+ height: 100%; |
+ padding: 1em; |
+ } |
+ |
+ /* tables */ |
+ .table { |
+ border-collapse: collapse!important; |
+ table-layout: fixed; |
+ height: 100%; |
+ } |
+ .th, .td { |
+ padding: 8px; |
+ vertical-align: top; |
+ } |
+ .table thead > tr > th { |
+ vertical-align: bottom; |
+ text-align: left; |
+ border-bottom:2px solid #ddd; |
+ } |
+ .spacer { |
+ width: 16px; |
+ } |
+ .left-border-spacer { |
+ width: 16px; |
+ border-left: 1px solid; |
+ } |
+ .clickable { |
+ color: #0489c3; |
+ text-decoration: none; |
+ cursor: pointer; |
+ min-width: 8em; |
+ } |
+ .clickable:hover { |
+ text-decoration: underline; |
+ cursor: pointer; |
+ } |
+ tr:hover:not(.focused) > td { |
+ background-color: #FAFAFA; |
+ } |
+ .focused { |
+ background-color: #F4C7C3; |
+ } |
+ .scroll { |
+ overflow: scroll; |
+ } |
+ .outlined { |
+ -webkit-box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75); |
+ -moz-box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75); |
+ box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75); |
+ margin: 4px; |
+ } |
+ .centered { |
+ margin-left: auto; |
+ margin-right: auto; |
+ justify-content: center; |
+ } |
+ .full-height { |
+ height: 100%; |
+ } |
+ .mostly-full-height { |
+ height: 80%; |
+ } |
+ .full-width { |
+ width: 100%; |
+ } |
+ .focused-function-label { |
+ flex: 0 1 auto; |
+ margin-left: auto; |
+ margin-right: auto; |
+ justify-content: center; |
+ } |
+ .call-table { |
+ flex: 1 1 auto; |
+ } |
+ |
+ .tree { |
+ border-spacing: 0px; |
+ width: 100%; |
+ margin-bottom: 20px |
+ vertical-align: middle; |
+ } |
+ |
+ .tree tbody tr { |
+ animation: fadeIn 0.5s; |
+ -moz-animation: fadeIn 0.5s; |
+ -webkit-animation: fadeIn 0.5s; |
+ } |
+ |
+ .tree tbody tr:hover { |
+ background-color: #FAFAFA; |
+ } |
+ |
+ .tree tr td:first-child, |
+ .tree tr th:first-child { |
+ width: 100%; |
+ } |
+ |
+ .tree thead > tr > th { |
+ padding: 8px; |
+ vertical-align: bottom; |
+ text-align: left; |
+ border-bottom: 1px solid #ddd; |
+ } |
+ |
+ </style> |
+ <div class="content-centered-big"> |
+ <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">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> |
+ </div> |
+ <hr> |
+ <div id="main" class="flex-row centered"> |
+ <div class="flex-item-45-percent full-height outlined scroll"> |
+ <table id="main-table" class="flex-item-100-percent table"> |
+ <thead> |
+ <tr> |
+ <th on-click="{{changeSortProfile}}" class="clickable" title="Executing (%)">{{ profileTable.getColumnLabel(0) }}</th> |
+ <th on-click="{{changeSortProfile}}" class="clickable" title="In stack (%)">{{ profileTable.getColumnLabel(1) }}</th> |
+ <th on-click="{{changeSortProfile}}" class="clickable" title="Method">{{ profileTable.getColumnLabel(2) }}</th> |
+ </tr> |
+ </thead> |
+ <tbody id="profile-table"> |
+ </tbody> |
+ </table> |
+ </div> |
+ <div class="flex-item-45-percent full-height outlined"> |
+ <div class="flex-column full-height"> |
+ <div class="focused-function-label"> |
+ <template if="{{ focusedFunction != null }}"> |
+ <span>Focused on: </span> |
+ <function-ref ref="{{ focusedFunction }}"></function-ref> |
+ </template> |
+ <template if="{{ focusedFunction == null }}"> |
+ <span>No focused function</span> |
+ </template> |
+ </div> |
+ <hr> |
+ <div class="call-table scroll"> |
+ <table class="full-width table"> |
+ <thead> |
+ <tr> |
+ <th on-click="{{changeSortCallers}}" class="clickable" title="Callers (%)">{{ profileCallersTable.getColumnLabel(0) }}</th> |
+ <th on-click="{{changeSortCallers}}" class="clickable" title="Method">{{ profileCallersTable.getColumnLabel(1) }}</th> |
+ </tr> |
+ </thead> |
+ <tbody id="callers-table"> |
+ </tbody> |
+ </table> |
+ </div> |
+ <hr> |
+ <div class="call-table scroll"> |
+ <table class="full-width table"> |
+ <thead> |
+ <tr> |
+ <th on-click="{{changeSortCallees}}" class="clickable" title="Callees (%)">{{ profileCalleesTable.getColumnLabel(0) }}</th> |
+ <th on-click="{{changeSortCallees}}" class="clickable" title="Method">{{ profileCalleesTable.getColumnLabel(1) }}</th> |
+ </tr> |
+ </thead> |
+ <tbody id="callees-table"> |
+ </tbody> |
+ </table> |
+ </div> |
+ </div> |
+ </div> |
+ </div> |
+ <br> |
+ <br> |
+ <div class="focused-function-label"> |
+ <template if="{{ focusedFunction != null }}"> |
+ <span>Filtered tree: </span> |
+ <function-ref ref="{{ focusedFunction }}"></function-ref> |
+ </template> |
+ <template if="{{ focusedFunction == null }}"> |
+ <span>No focused function</span> |
+ </template> |
+ </div> |
+ <div class="flex-row centered"> |
+ <div class="flex-item-90-percent outlined" style="margin: 16px; margin-left: 8px; margin-right: 8px"> |
+ <table class="full-width tree"> |
+ <thead id="treeHeader"> |
+ <tr> |
+ <th>Method</th> |
+ <th>Executing</th> |
+ </tr> |
+ </thead> |
+ <tbody id="treeBody"> |
+ </tbody> |
+ </table> |
+ </div> |
+ </div> |
+ </template> |
+</polymer-element> |
+ |
<polymer-element name="cpu-profile" extends="observatory-element"> |
<template> |
<link rel="stylesheet" href="css/shared.css"> |
@@ -14,7 +279,6 @@ |
<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 { |
@@ -192,7 +456,7 @@ |
<thead id="treeHeader"> |
<tr> |
<th>Method</th> |
- <th>Self</th> |
+ <th>Executing</th> |
</tr> |
</thead> |
<tbody id="treeBody"> |