| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.vmstats; | 5 part of dart.vmstats; |
| 6 | 6 |
| 7 class IsolateList { | 7 class IsolateList { |
| 8 UListElement _listArea; | 8 TableElement _isolateTable; |
| 9 | 9 |
| 10 static const String CSS_VISIBLE = 'isolate_details'; | 10 static const String DETAILS = 'isolate_details'; |
| 11 static const String CSS_HIDDEN = 'isolate_details_hidden'; | 11 static const String VISIBLE = 'visible'; |
| 12 static const String HIDDEN = 'hidden'; |
| 13 static const String ISOLATE_LIST_ITEM = 'isolate_list_item'; |
| 14 static const String ISOLATE_DETAILS_COLUMN = 'isolate_details_column'; |
| 15 static const String ISOLATE_ROW = 'isolate_row'; |
| 16 static const String ISOLATE_STACKTRACE_COLUMN = 'isolate_stacktrace_column'; |
| 17 static const String NEW_SPACE = 'new_space'; |
| 18 static const String OLD_SPACE = 'old_space'; |
| 19 static const String STACK_FRAME = 'stack_frame'; |
| 20 static const String STACK_LIMIT = 'stack_limit'; |
| 21 static const String STACK_TRACE = 'stack_trace'; |
| 22 static const String STACK_TRACE_TITLE = 'stack_trace_title'; |
| 12 | 23 |
| 13 IsolateList(this._listArea) {} | 24 IsolateList(this._isolateTable) {} |
| 14 | 25 |
| 15 void updateList(IsolateListModel model) { | 26 void updateList(IsolateListModel model) { |
| 16 var detailsClass = CSS_HIDDEN; | |
| 17 if (_listArea.children.length > 0) { | |
| 18 // Preserve visibility state. | |
| 19 var listItem = _listArea.children.first; | |
| 20 var item = listItem.children.first; | |
| 21 if (item.classes.length > 0 && item.classes.first == CSS_VISIBLE) { | |
| 22 detailsClass = CSS_VISIBLE; | |
| 23 } | |
| 24 _listArea.children.clear(); | |
| 25 } | |
| 26 var iterator = model.iterator; | 27 var iterator = model.iterator; |
| 27 while (iterator.moveNext()) { | 28 while (iterator.moveNext()) { |
| 28 var isolate = iterator.current; | 29 var isolate = iterator.current; |
| 29 var listItem = new LIElement(); | 30 var isolateId = 'isolate-${isolate.port}'; |
| 30 listItem.classes.add('isolate_list'); | 31 var isolateRow = _isolateTable.query('#$isolateId'); |
| 31 listItem.text = isolate.name | 32 if (isolateRow != null) { |
| 33 updateIsolateDetails(isolate, isolateRow); |
| 34 } else { |
| 35 isolateRow = new TableRowElement(); |
| 36 isolateRow.$dom_className = ISOLATE_ROW; |
| 37 isolateRow.id = isolateId; |
| 38 _isolateTable.children.add(isolateRow); |
| 39 var detailsCell = new TableCellElement(); |
| 40 detailsCell.$dom_className = ISOLATE_DETAILS_COLUMN; |
| 41 isolateRow.children.add(detailsCell); |
| 42 var basicData = new DivElement(); |
| 43 basicData.text = isolate.name |
| 32 .replaceAll('\$', ': ') // Split script from isolate, and ... | 44 .replaceAll('\$', ': ') // Split script from isolate, and ... |
| 33 .replaceAll('-', ' '); // ... split name from port number. | 45 .replaceAll('-', ' '); // ... split name from port number. |
| 46 detailsCell.children.add(basicData); |
| 34 | 47 |
| 35 // Add isolate details as hidden children. | 48 // Add isolate details as hidden children. |
| 36 var details = new DivElement(); | 49 var details = new DivElement(); |
| 37 isolateDetails(isolate, details); | 50 details.classes.addAll([DETAILS, HIDDEN]); |
| 38 details.classes.add(detailsClass); | 51 detailsCell.children.add(details); |
| 39 listItem.children.add(details); | |
| 40 listItem.onClick.listen((e) => toggle(details)); | |
| 41 | 52 |
| 42 _listArea.children.add(listItem); | 53 // Add stacktrace column. |
| 54 var stacktraceCell = new TableCellElement(); |
| 55 stacktraceCell.classes.addAll([ISOLATE_STACKTRACE_COLUMN, HIDDEN]); |
| 56 isolateRow.children.add(stacktraceCell); |
| 57 var stacktrace = new DivElement(); |
| 58 stacktrace.classes.addAll([STACK_TRACE, HIDDEN]); |
| 59 stacktraceCell.children.add(stacktrace); |
| 60 |
| 61 isolateRow.onClick.listen((e) => toggle(isolateRow)); |
| 62 updateIsolateDetails(isolate, isolateRow); |
| 63 } |
| 43 } | 64 } |
| 44 } | 65 } |
| 45 | 66 |
| 46 void isolateDetails(Isolate isolate, DivElement parent) { | 67 void setStacktrace(DivElement element, String json) { |
| 47 var newSpace = new DivElement(); | 68 element.children.clear(); |
| 48 newSpace.text = 'New space: ${isolate.newSpace.used}K'; | 69 var response = JSON.parse(json); |
| 49 parent.children.add(newSpace); | 70 element.id = response['handle']; |
| 50 var oldSpace = new DivElement(); | 71 var title = new DivElement(); |
| 51 oldSpace.text = 'Old space: ${isolate.oldSpace.used}K'; | 72 title.$dom_className = STACK_TRACE_TITLE; |
| 52 parent.children.add(oldSpace); | 73 title.text = "Stack Trace"; |
| 53 var stack = new DivElement(); | 74 element.children.add(title); |
| 54 stack.text = 'Stack limit: ${(isolate.stackLimit / 1000000).round()}M'; | 75 |
| 55 parent.children.add(stack); | 76 var stackIterator = response['stacktrace'].iterator; |
| 77 var i = 0; |
| 78 while (stackIterator.moveNext()) { |
| 79 i++; |
| 80 var frame = stackIterator.current; |
| 81 var frameElement = new DivElement(); |
| 82 frameElement.$dom_className = STACK_FRAME; |
| 83 var text = '$i: ${frame["url"]}:${frame["line"]}: ${frame["function"]}'; |
| 84 var code = frame["code"]; |
| 85 if (code['optimized']) { |
| 86 text = '$text (optimized)'; |
| 87 } |
| 88 frameElement.text = text; |
| 89 element.children.add(frameElement); |
| 90 } |
| 56 } | 91 } |
| 57 | 92 |
| 58 void toggle(DivElement e) { | 93 Element findOrAddChild(DivElement parent, String className) { |
| 59 e.classes.toggle(CSS_VISIBLE); | 94 var child = parent.query('.$className'); |
| 60 e.classes.toggle(CSS_HIDDEN); | 95 if (child == null) { |
| 96 child = new DivElement(); |
| 97 child.$dom_className = className; |
| 98 parent.children.add(child); |
| 99 } |
| 100 return child; |
| 101 } |
| 102 |
| 103 void updateIsolateDetails(Isolate isolate, TableRowElement row) { |
| 104 var details = row.query('.$DETAILS'); |
| 105 var newSpace = findOrAddChild(details, NEW_SPACE); |
| 106 newSpace.text = 'New space: ${isolate.newSpace.used}K'; |
| 107 var oldSpace = findOrAddChild(details, OLD_SPACE); |
| 108 oldSpace.text = 'Old space: ${isolate.oldSpace.used}K'; |
| 109 var stackLimit = findOrAddChild(details, STACK_LIMIT); |
| 110 stackLimit.text = |
| 111 'Stack limit: ${(isolate.stackLimit.abs() / 1000000).round()}M'; |
| 112 var stackTrace = findOrAddChild(row, ISOLATE_STACKTRACE_COLUMN); |
| 113 HttpRequest.getString('/isolate/${isolate.handle}/stacktrace').then( |
| 114 (String response) => setStacktrace(stackTrace, response)); |
| 115 } |
| 116 |
| 117 void toggle(TableRowElement row) { |
| 118 var details = row.query('.$DETAILS'); |
| 119 details.classes.toggle(VISIBLE); |
| 120 details.classes.toggle(HIDDEN); |
| 121 var stacktrace = row.query('.$ISOLATE_STACKTRACE_COLUMN'); |
| 122 stacktrace.classes.toggle(VISIBLE); |
| 123 stacktrace.classes.toggle(HIDDEN); |
| 61 } | 124 } |
| 62 } | 125 } |
| OLD | NEW |