• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5function inherits(childCtor, parentCtor) {
6  childCtor.prototype.__proto__ = parentCtor.prototype;
7};
8
9/**
10 * A thin wrapper around shell's 'read' function showing a file name on error.
11 */
12function readFile(fileName) {
13  try {
14    return read(fileName);
15  } catch (e) {
16    print(fileName + ': ' + (e.message || e));
17    throw e;
18  }
19}
20
21/**
22 * Parser for dynamic code optimization state.
23 */
24function parseState(s) {
25  switch (s) {
26  case "": return Profile.CodeState.COMPILED;
27  case "~": return Profile.CodeState.OPTIMIZABLE;
28  case "*": return Profile.CodeState.OPTIMIZED;
29  }
30  throw new Error("unknown code state: " + s);
31}
32
33
34function IcProcessor() {
35  var propertyICParser = [parseInt, parseInt, parseInt, parseString,
36      parseString, parseInt, parseString, parseString, parseString];
37  LogReader.call(this, {
38      'code-creation': {
39          parsers: [parseString, parseInt, parseInt, parseInt, parseInt,
40              parseString, parseVarArgs],
41          processor: this.processCodeCreation },
42      'code-move': { parsers: [parseInt, parseInt],
43          processor: this.processCodeMove },
44      'code-delete': { parsers: [parseInt],
45          processor: this.processCodeDelete },
46      'sfi-move': { parsers: [parseInt, parseInt],
47          processor: this.processFunctionMove },
48      'LoadIC': {
49        parsers : propertyICParser,
50        processor: this.processPropertyIC.bind(this, "LoadIC") },
51      'StoreIC': {
52        parsers : propertyICParser,
53        processor: this.processPropertyIC.bind(this, "StoreIC") },
54      'KeyedLoadIC': {
55        parsers : propertyICParser,
56        processor: this.processPropertyIC.bind(this, "KeyedLoadIC") },
57      'KeyedStoreIC': {
58        parsers : propertyICParser,
59        processor: this.processPropertyIC.bind(this, "KeyedStoreIC") },
60      'StoreInArrayLiteralIC': {
61        parsers : propertyICParser,
62        processor: this.processPropertyIC.bind(this, "StoreInArrayLiteralIC") },
63      });
64  this.profile_ = new Profile();
65
66  this.LoadIC = 0;
67  this.StoreIC = 0;
68  this.KeyedLoadIC = 0;
69  this.KeyedStoreIC = 0;
70  this.StoreInArrayLiteralIC = 0;
71}
72inherits(IcProcessor, LogReader);
73
74/**
75 * @override
76 */
77IcProcessor.prototype.printError = function(str) {
78  print(str);
79};
80
81IcProcessor.prototype.processString = function(string) {
82  var end = string.length;
83  var current = 0;
84  var next = 0;
85  var line;
86  var i = 0;
87  var entry;
88  while (current < end) {
89    next = string.indexOf("\n", current);
90    if (next === -1) break;
91    i++;
92    line = string.substring(current, next);
93    current = next + 1;
94    this.processLogLine(line);
95  }
96}
97
98IcProcessor.prototype.processLogFile = function(fileName) {
99  this.collectEntries = true
100  this.lastLogFileName_ = fileName;
101  var line;
102  while (line = readline()) {
103    this.processLogLine(line);
104  }
105  print();
106  print("=====================");
107  print("Load: " + this.LoadIC);
108  print("Store: " + this.StoreIC);
109  print("KeyedLoad: " + this.KeyedLoadIC);
110  print("KeyedStore: " + this.KeyedStoreIC);
111  print("StoreInArrayLiteral: " + this.StoreInArrayLiteralIC);
112};
113
114IcProcessor.prototype.addEntry = function(entry) {
115  this.entries.push(entry);
116}
117
118IcProcessor.prototype.processCodeCreation = function(
119    type, kind, timestamp, start, size, name, maybe_func) {
120  if (maybe_func.length) {
121    var funcAddr = parseInt(maybe_func[0]);
122    var state = parseState(maybe_func[1]);
123    this.profile_.addFuncCode(type, name, timestamp, start, size, funcAddr, state);
124  } else {
125    this.profile_.addCode(type, name, timestamp, start, size);
126  }
127};
128
129
130IcProcessor.prototype.processCodeMove = function(from, to) {
131  this.profile_.moveCode(from, to);
132};
133
134
135IcProcessor.prototype.processCodeDelete = function(start) {
136  this.profile_.deleteCode(start);
137};
138
139
140IcProcessor.prototype.processFunctionMove = function(from, to) {
141  this.profile_.moveFunc(from, to);
142};
143
144IcProcessor.prototype.formatName = function(entry) {
145  if (!entry) return "<unknown>"
146  var name = entry.func.getName();
147  var re = /(.*):[0-9]+:[0-9]+$/;
148  var array = re.exec(name);
149  if (!array) return name;
150  return entry.getState() + array[1];
151}
152
153IcProcessor.prototype.processPropertyIC = function (
154    type, pc, line, column, old_state, new_state, map, name, modifier,
155    slow_reason) {
156  this[type]++;
157  var entry = this.profile_.findEntry(pc);
158  print(type + " (" + old_state + "->" + new_state + modifier + ") at " +
159        this.formatName(entry) + ":" + line + ":" + column + " " + name +
160        " (map 0x" + map.toString(16) + ")" +
161        (slow_reason ? " " + slow_reason : ""));
162}
163
164
165class ArgumentsProcessor extends BaseArgumentsProcessor {
166  getArgsDispatch() {
167    return {
168      '--range': ['range', 'auto,auto',
169          'Specify the range limit as [start],[end]'],
170      '--source-map': ['sourceMap', null,
171          'Specify the source map that should be used for output']
172    };
173  }
174  getDefaultResults() {
175   return {
176      logFileName: 'v8.log',
177      range: 'auto,auto',
178    };
179  }
180}
181