Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: tools/profile.js

Issue 2696903002: [profiler] Graphical front-end for tick processor. (Closed)
Patch Set: Fix test Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/mac-nm ('k') | tools/profview/index.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 19 matching lines...) Expand all
30 * Creates a profile object for processing profiling-related events 30 * Creates a profile object for processing profiling-related events
31 * and calculating function execution times. 31 * and calculating function execution times.
32 * 32 *
33 * @constructor 33 * @constructor
34 */ 34 */
35 function Profile() { 35 function Profile() {
36 this.codeMap_ = new CodeMap(); 36 this.codeMap_ = new CodeMap();
37 this.topDownTree_ = new CallTree(); 37 this.topDownTree_ = new CallTree();
38 this.bottomUpTree_ = new CallTree(); 38 this.bottomUpTree_ = new CallTree();
39 this.c_entries_ = {}; 39 this.c_entries_ = {};
40 this.ticks_ = [];
40 }; 41 };
41 42
42 43
43 /** 44 /**
44 * Returns whether a function with the specified name must be skipped. 45 * Returns whether a function with the specified name must be skipped.
45 * Should be overriden by subclasses. 46 * Should be overriden by subclasses.
46 * 47 *
47 * @param {string} name Function name. 48 * @param {string} name Function name.
48 */ 49 */
49 Profile.prototype.skipThisFunction = function(name) { 50 Profile.prototype.skipThisFunction = function(name) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 return this.codeMap_.findEntry(addr); 229 return this.codeMap_.findEntry(addr);
229 }; 230 };
230 231
231 232
232 /** 233 /**
233 * Records a tick event. Stack must contain a sequence of 234 * Records a tick event. Stack must contain a sequence of
234 * addresses starting with the program counter value. 235 * addresses starting with the program counter value.
235 * 236 *
236 * @param {Array<number>} stack Stack sample. 237 * @param {Array<number>} stack Stack sample.
237 */ 238 */
238 Profile.prototype.recordTick = function(stack) { 239 Profile.prototype.recordTick = function(time_ns, vmState, stack) {
239 var processedStack = this.resolveAndFilterFuncs_(stack); 240 var processedStack = this.resolveAndFilterFuncs_(stack);
240 this.bottomUpTree_.addPath(processedStack); 241 this.bottomUpTree_.addPath(processedStack);
241 processedStack.reverse(); 242 processedStack.reverse();
242 this.topDownTree_.addPath(processedStack); 243 this.topDownTree_.addPath(processedStack);
243 }; 244 };
244 245
245 246
246 /** 247 /**
247 * Translates addresses into function names and filters unneeded 248 * Translates addresses into function names and filters unneeded
248 * functions. 249 * functions.
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 labels, opt_f) { 826 labels, opt_f) {
826 for (var pos = 0, curr = this; pos < labels.length && curr != null; pos++) { 827 for (var pos = 0, curr = this; pos < labels.length && curr != null; pos++) {
827 var child = curr.findChild(labels[pos]); 828 var child = curr.findChild(labels[pos]);
828 if (opt_f) { 829 if (opt_f) {
829 opt_f(child, pos); 830 opt_f(child, pos);
830 } 831 }
831 curr = child; 832 curr = child;
832 } 833 }
833 return curr; 834 return curr;
834 }; 835 };
836
837 function JsonProfile() {
838 this.codeMap_ = new CodeMap();
839 this.codeEntries_ = [];
840 this.functionEntries_ = [];
841 this.ticks_ = [];
842 }
843
844 JsonProfile.prototype.addLibrary = function(
845 name, startAddr, endAddr) {
846 var entry = new CodeMap.CodeEntry(
847 endAddr - startAddr, name, 'SHARED_LIB');
848 this.codeMap_.addLibrary(startAddr, entry);
849
850 entry.codeId = this.codeEntries_.length;
851 this.codeEntries_.push({name : entry.name, type : entry.type});
852 return entry;
853 };
854
855 JsonProfile.prototype.addStaticCode = function(
856 name, startAddr, endAddr) {
857 var entry = new CodeMap.CodeEntry(
858 endAddr - startAddr, name, 'CPP');
859 this.codeMap_.addStaticCode(startAddr, entry);
860
861 entry.codeId = this.codeEntries_.length;
862 this.codeEntries_.push({name : entry.name, type : entry.type});
863 return entry;
864 };
865
866 JsonProfile.prototype.addCode = function(
867 kind, name, start, size) {
868 var entry = new CodeMap.CodeEntry(size, name, 'CODE');
869 this.codeMap_.addCode(start, entry);
870
871 entry.codeId = this.codeEntries_.length;
872 this.codeEntries_.push({name : entry.name, type : entry.type, kind : kind});
873
874 return entry;
875 };
876
877 JsonProfile.prototype.addFuncCode = function(
878 kind, name, start, size, funcAddr, state) {
879 // As code and functions are in the same address space,
880 // it is safe to put them in a single code map.
881 var func = this.codeMap_.findDynamicEntryByStartAddress(funcAddr);
882 if (!func) {
883 var func = new CodeMap.CodeEntry(0, name, 'SFI');
884 this.codeMap_.addCode(funcAddr, func);
885
886 func.funcId = this.functionEntries_.length;
887 this.functionEntries_.push({name : name, codes : []});
888 } else if (func.name !== name) {
889 // Function object has been overwritten with a new one.
890 func.name = name;
891
892 func.funcId = this.functionEntries_.length;
893 this.functionEntries_.push({name : name, codes : []});
894 }
895 // TODO(jarin): Insert the code object into the SFI's code list.
896 var entry = this.codeMap_.findDynamicEntryByStartAddress(start);
897 if (entry) {
898 // TODO(jarin) This does not look correct, we should really
899 // update the code object (remove the old one and insert this one).
900 if (entry.size === size && entry.func === func) {
901 // Entry state has changed.
902 entry.state = state;
903 }
904 } else {
905 var entry = new CodeMap.CodeEntry(size, name, 'JS');
906 this.codeMap_.addCode(start, entry);
907
908 entry.codeId = this.codeEntries_.length;
909
910 this.functionEntries_[func.funcId].codes.push(entry.codeId);
911
912 if (state === 0) {
913 kind = "Builtin";
914 } else if (state === 1) {
915 kind = "Unopt";
916 } else if (state === 2) {
917 kind = "Opt";
918 }
919
920 this.codeEntries_.push({
921 name : entry.name,
922 type : entry.type,
923 kind : kind,
924 func : func.funcId
925 });
926 }
927 return entry;
928 };
929
930 JsonProfile.prototype.moveCode = function(from, to) {
931 try {
932 this.codeMap_.moveCode(from, to);
933 } catch (e) {
934 printErr("Move: unknown source " + from);
935 }
936 };
937
938 JsonProfile.prototype.deleteCode = function(start) {
939 try {
940 this.codeMap_.deleteCode(start);
941 } catch (e) {
942 printErr("Delete: unknown address " + start);
943 }
944 };
945
946 JsonProfile.prototype.moveFunc = function(from, to) {
947 if (this.codeMap_.findDynamicEntryByStartAddress(from)) {
948 this.codeMap_.moveCode(from, to);
949 }
950 };
951
952 JsonProfile.prototype.findEntry = function(addr) {
953 return this.codeMap_.findEntry(addr);
954 };
955
956 JsonProfile.prototype.recordTick = function(time_ns, vmState, stack) {
957 // TODO(jarin) Resolve the frame-less case (when top of stack is
958 // known code).
959 var processedStack = [];
960 for (var i = 0; i < stack.length; i++) {
961 var resolved = this.codeMap_.findAddress(stack[i]);
962 if (resolved) {
963 processedStack.push(resolved.entry.codeId, resolved.offset);
964 } else {
965 processedStack.push(-1, stack[i]);
966 }
967 }
968 this.ticks_.push({ tm : time_ns, vm : vmState, s : processedStack });
969 };
970
971 JsonProfile.prototype.writeJson = function() {
972 var toplevel = {
973 code : this.codeEntries_,
974 functions : this.functionEntries_,
975 ticks : this.ticks_
976 };
977 write(JSON.stringify(toplevel));
978 };
OLDNEW
« no previous file with comments | « tools/mac-nm ('k') | tools/profview/index.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698