logreader.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // Copyright 2011 the V8 project authors. All rights reserved.
  2. // Redistribution and use in source and binary forms, with or without
  3. // modification, are permitted provided that the following conditions are
  4. // met:
  5. //
  6. // * Redistributions of source code must retain the above copyright
  7. // notice, this list of conditions and the following disclaimer.
  8. // * Redistributions in binary form must reproduce the above
  9. // copyright notice, this list of conditions and the following
  10. // disclaimer in the documentation and/or other materials provided
  11. // with the distribution.
  12. // * Neither the name of Google Inc. nor the names of its
  13. // contributors may be used to endorse or promote products derived
  14. // from this software without specific prior written permission.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  18. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  19. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  20. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  21. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  22. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. /**
  28. * @fileoverview Log Reader is used to process log file produced by V8.
  29. */
  30. /**
  31. * Base class for processing log files.
  32. *
  33. * @param {Array.<Object>} dispatchTable A table used for parsing and processing
  34. * log records.
  35. * @constructor
  36. */
  37. function LogReader(dispatchTable) {
  38. /**
  39. * @type {Array.<Object>}
  40. */
  41. this.dispatchTable_ = dispatchTable;
  42. /**
  43. * Current line.
  44. * @type {number}
  45. */
  46. this.lineNum_ = 0;
  47. /**
  48. * CSV lines parser.
  49. * @type {CsvParser}
  50. */
  51. this.csvParser_ = new CsvParser();
  52. };
  53. /**
  54. * Used for printing error messages.
  55. *
  56. * @param {string} str Error message.
  57. */
  58. LogReader.prototype.printError = function(str) {
  59. // Do nothing.
  60. };
  61. /**
  62. * Processes a portion of V8 profiler event log.
  63. *
  64. * @param {string} chunk A portion of log.
  65. */
  66. LogReader.prototype.processLogChunk = function(chunk) {
  67. this.processLog_(chunk.split('\n'));
  68. };
  69. /**
  70. * Processes a line of V8 profiler event log.
  71. *
  72. * @param {string} line A line of log.
  73. */
  74. LogReader.prototype.processLogLine = function(line) {
  75. this.processLog_([line]);
  76. };
  77. /**
  78. * Processes stack record.
  79. *
  80. * @param {number} pc Program counter.
  81. * @param {number} func JS Function.
  82. * @param {Array.<string>} stack String representation of a stack.
  83. * @return {Array.<number>} Processed stack.
  84. */
  85. LogReader.prototype.processStack = function(pc, func, stack) {
  86. var fullStack = func ? [pc, func] : [pc];
  87. var prevFrame = pc;
  88. for (var i = 0, n = stack.length; i < n; ++i) {
  89. var frame = stack[i];
  90. var firstChar = frame.charAt(0);
  91. if (firstChar == '+' || firstChar == '-') {
  92. // An offset from the previous frame.
  93. prevFrame += parseInt(frame, 16);
  94. fullStack.push(prevFrame);
  95. // Filter out possible 'overflow' string.
  96. } else if (firstChar != 'o') {
  97. fullStack.push(parseInt(frame, 16));
  98. }
  99. }
  100. return fullStack;
  101. };
  102. /**
  103. * Returns whether a particular dispatch must be skipped.
  104. *
  105. * @param {!Object} dispatch Dispatch record.
  106. * @return {boolean} True if dispatch must be skipped.
  107. */
  108. LogReader.prototype.skipDispatch = function(dispatch) {
  109. return false;
  110. };
  111. /**
  112. * Does a dispatch of a log record.
  113. *
  114. * @param {Array.<string>} fields Log record.
  115. * @private
  116. */
  117. LogReader.prototype.dispatchLogRow_ = function(fields) {
  118. // Obtain the dispatch.
  119. var command = fields[0];
  120. if (!(command in this.dispatchTable_)) return;
  121. var dispatch = this.dispatchTable_[command];
  122. if (dispatch === null || this.skipDispatch(dispatch)) {
  123. return;
  124. }
  125. // Parse fields.
  126. var parsedFields = [];
  127. for (var i = 0; i < dispatch.parsers.length; ++i) {
  128. var parser = dispatch.parsers[i];
  129. if (parser === null) {
  130. parsedFields.push(fields[1 + i]);
  131. } else if (typeof parser == 'function') {
  132. parsedFields.push(parser(fields[1 + i]));
  133. } else {
  134. // var-args
  135. parsedFields.push(fields.slice(1 + i));
  136. break;
  137. }
  138. }
  139. // Run the processor.
  140. dispatch.processor.apply(this, parsedFields);
  141. };
  142. /**
  143. * Processes log lines.
  144. *
  145. * @param {Array.<string>} lines Log lines.
  146. * @private
  147. */
  148. LogReader.prototype.processLog_ = function(lines) {
  149. for (var i = 0, n = lines.length; i < n; ++i, ++this.lineNum_) {
  150. var line = lines[i];
  151. if (!line) {
  152. continue;
  153. }
  154. try {
  155. var fields = this.csvParser_.parseLine(line);
  156. this.dispatchLogRow_(fields);
  157. } catch (e) {
  158. this.printError('line ' + (this.lineNum_ + 1) + ': ' + (e.message || e));
  159. }
  160. }
  161. };