OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 25 matching lines...) Expand all Loading... |
36 throw new Error("unknown code state: " + s); | 36 throw new Error("unknown code state: " + s); |
37 } | 37 } |
38 | 38 |
39 function LogProcessor() { | 39 function LogProcessor() { |
40 LogReader.call(this, { | 40 LogReader.call(this, { |
41 'code-creation': { | 41 'code-creation': { |
42 parsers: [null, parseInt, parseInt, null, 'var-args'], | 42 parsers: [null, parseInt, parseInt, null, 'var-args'], |
43 processor: this.processCodeCreation }, | 43 processor: this.processCodeCreation }, |
44 'code-move': { parsers: [parseInt, parseInt], | 44 'code-move': { parsers: [parseInt, parseInt], |
45 processor: this.processCodeMove }, | 45 processor: this.processCodeMove }, |
46 'code-delete': { parsers: [parseInt], | 46 'code-delete': null, |
47 processor: this.processCodeDelete }, | |
48 'sfi-move': { parsers: [parseInt, parseInt], | 47 'sfi-move': { parsers: [parseInt, parseInt], |
49 processor: this.processFunctionMove }, | 48 processor: this.processFunctionMove }, |
50 'shared-library': null, | 49 'shared-library': null, |
51 'profiler': null, | 50 'profiler': null, |
52 'tick': null }); | 51 'tick': null }); |
53 this.profile = new Profile(); | 52 this.profile = new Profile(); |
54 | 53 |
55 } | 54 } |
56 LogProcessor.prototype.__proto__ = LogReader.prototype; | 55 LogProcessor.prototype.__proto__ = LogReader.prototype; |
57 | 56 |
58 LogProcessor.prototype.processCodeCreation = function( | 57 LogProcessor.prototype.processCodeCreation = function( |
59 type, start, size, name, maybe_func) { | 58 type, start, size, name, maybe_func) { |
60 if (type != "LazyCompile" && type != "Script" && type != "Function") return; | 59 if (type != "LazyCompile" && type != "Script" && type != "Function") return; |
61 // Discard types to avoid discrepancies in "LazyCompile" vs. "Function". | 60 // Discard types to avoid discrepancies in "LazyCompile" vs. "Function". |
62 type = ""; | 61 type = ""; |
63 if (maybe_func.length) { | 62 if (maybe_func.length) { |
64 var funcAddr = parseInt(maybe_func[0]); | 63 var funcAddr = parseInt(maybe_func[0]); |
65 var state = parseState(maybe_func[1]); | 64 var state = parseState(maybe_func[1]); |
66 this.profile.addFuncCode(type, name, start, size, funcAddr, state); | 65 this.profile.addFuncCode(type, name, start, size, funcAddr, state); |
67 } else { | 66 } else { |
68 this.profile.addCode(type, name, start, size); | 67 this.profile.addCode(type, name, start, size); |
69 } | 68 } |
70 }; | 69 }; |
71 | 70 |
72 LogProcessor.prototype.processCodeMove = function(from, to) { | 71 LogProcessor.prototype.processCodeMove = function(from, to) { |
73 this.profile.moveCode(from, to); | 72 this.profile.moveCode(from, to); |
74 }; | 73 }; |
75 | 74 |
76 LogProcessor.prototype.processCodeDelete = function(start) { | |
77 this.profile.deleteCode(start); | |
78 }; | |
79 | |
80 LogProcessor.prototype.processFunctionMove = function(from, to) { | 75 LogProcessor.prototype.processFunctionMove = function(from, to) { |
81 this.profile.moveFunc(from, to); | 76 this.profile.moveFunc(from, to); |
82 }; | 77 }; |
83 | 78 |
84 function RunTest() { | 79 function RunTest() { |
85 // _log must be provided externally. | 80 // _log must be provided externally. |
86 var log_lines = _log.split("\n"); | 81 var log_lines = _log.split("\n"); |
87 var line, pos = 0, log_lines_length = log_lines.length; | 82 var line, pos = 0, log_lines_length = log_lines.length; |
88 if (log_lines_length < 2) | 83 if (log_lines_length < 2) |
89 return "log_lines_length < 2"; | 84 return "log_lines_length < 2"; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 return true; | 120 return true; |
126 } | 121 } |
127 if (entityNamesEqual.builtins.indexOf(entityB.getName()) !== -1) return true
; | 122 if (entityNamesEqual.builtins.indexOf(entityB.getName()) !== -1) return true
; |
128 return entityA.getName() === entityB.getName(); | 123 return entityA.getName() === entityB.getName(); |
129 } | 124 } |
130 entityNamesEqual.builtins = | 125 entityNamesEqual.builtins = |
131 ["Boolean", "Function", "Number", "Object", | 126 ["Boolean", "Function", "Number", "Object", |
132 "Script", "String", "RegExp", "Date", "Error"]; | 127 "Script", "String", "RegExp", "Date", "Error"]; |
133 | 128 |
134 function entitiesEqual(entityA, entityB) { | 129 function entitiesEqual(entityA, entityB) { |
135 if (entityA === null && entityB !== null) return true; | 130 if ((entityA === null && entityB !== null) || |
136 if (entityA !== null && entityB === null) return false; | 131 (entityA !== null && entityB === null)) return true; |
137 return entityA.size === entityB.size && entityNamesEqual(entityA, entityB); | 132 return entityA.size === entityB.size && entityNamesEqual(entityA, entityB); |
138 } | 133 } |
139 | 134 |
140 var l_pos = 0, t_pos = 0; | 135 var l_pos = 0, t_pos = 0; |
141 var l_len = logging_entries.length, t_len = traversal_entries.length; | 136 var l_len = logging_entries.length, t_len = traversal_entries.length; |
142 var comparison = []; | 137 var comparison = []; |
143 var equal = true; | 138 var equal = true; |
144 // Do a merge-like comparison of entries. At the same address we expect to | 139 // Do a merge-like comparison of entries. At the same address we expect to |
145 // find the same entries. We skip builtins during log parsing, but compiled | 140 // find the same entries. We skip builtins during log parsing, but compiled |
146 // functions traversal may erroneously recognize them as functions, so we are | 141 // functions traversal may erroneously recognize them as functions, so we are |
147 // expecting more functions in traversal vs. logging. | 142 // expecting more functions in traversal vs. logging. |
| 143 // Since we don't track code deletions, logging can also report more entries |
| 144 // than traversal. |
148 while (l_pos < l_len && t_pos < t_len) { | 145 while (l_pos < l_len && t_pos < t_len) { |
149 var entryA = logging_entries[l_pos]; | 146 var entryA = logging_entries[l_pos]; |
150 var entryB = traversal_entries[t_pos]; | 147 var entryB = traversal_entries[t_pos]; |
151 var cmp = addressComparator(entryA, entryB); | 148 var cmp = addressComparator(entryA, entryB); |
152 var entityA = entryA[1], entityB = entryB[1]; | 149 var entityA = entryA[1], entityB = entryB[1]; |
153 var address = entryA[0]; | 150 var address = entryA[0]; |
154 if (cmp < 0) { | 151 if (cmp < 0) { |
155 ++l_pos; | 152 ++l_pos; |
156 entityB = null; | 153 entityB = null; |
157 } else if (cmp > 0) { | 154 } else if (cmp > 0) { |
158 ++t_pos; | 155 ++t_pos; |
159 entityA = null; | 156 entityA = null; |
160 address = entryB[0]; | 157 address = entryB[0]; |
161 } else { | 158 } else { |
162 ++l_pos; | 159 ++l_pos; |
163 ++t_pos; | 160 ++t_pos; |
164 } | 161 } |
165 var entities_equal = entitiesEqual(entityA, entityB); | 162 var entities_equal = entitiesEqual(entityA, entityB); |
166 if (!entities_equal) equal = false; | 163 if (!entities_equal) equal = false; |
167 comparison.push([entities_equal, address, entityA, entityB]); | 164 comparison.push([entities_equal, address, entityA, entityB]); |
168 } | 165 } |
169 if (l_pos < l_len) equal = false; | |
170 while (l_pos < l_len) { | |
171 var entryA = logging_entries[l_pos++]; | |
172 comparison.push([false, entryA[0], entryA[1], null]); | |
173 } | |
174 return [equal, comparison]; | 166 return [equal, comparison]; |
175 } | 167 } |
176 | 168 |
177 var result = RunTest(); | 169 var result = RunTest(); |
178 if (typeof result !== "string") { | 170 if (typeof result !== "string") { |
179 var out = []; | 171 var out = []; |
180 if (!result[0]) { | 172 if (!result[0]) { |
181 var comparison = result[1]; | 173 var comparison = result[1]; |
182 for (var i = 0, l = comparison.length; i < l; ++i) { | 174 for (var i = 0, l = comparison.length; i < l; ++i) { |
183 var c = comparison[i]; | 175 var c = comparison[i]; |
184 out.push((c[0] ? " " : "* ") + | 176 out.push((c[0] ? " " : "* ") + |
185 c[1].toString(16) + " " + | 177 c[1].toString(16) + " " + |
186 (c[2] ? c[2] : "---") + " " + | 178 (c[2] ? c[2] : "---") + " " + |
187 (c[3] ? c[3] : "---")); | 179 (c[3] ? c[3] : "---")); |
188 } | 180 } |
189 } | 181 } |
190 result[0] ? true : out.join("\n"); | 182 result[0] ? true : out.join("\n"); |
191 } else { | 183 } else { |
192 result; | 184 result; |
193 } | 185 } |
OLD | NEW |