ic-processor.js 5.45 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

function inherits(childCtor, parentCtor) {
  childCtor.prototype.__proto__ = parentCtor.prototype;
};

/**
 * A thin wrapper around shell's 'read' function showing a file name on error.
 */
function readFile(fileName) {
  try {
    return read(fileName);
  } catch (e) {
    print(fileName + ': ' + (e.message || e));
    throw e;
  }
}

/**
 * Parser for dynamic code optimization state.
 */
function parseState(s) {
  switch (s) {
  case "": return Profile.CodeState.COMPILED;
  case "~": return Profile.CodeState.OPTIMIZABLE;
  case "*": return Profile.CodeState.OPTIMIZED;
  }
  throw new Error("unknown code state: " + s);
}


function IcProcessor() {
35 36 37
  var propertyICParser = [
    parseInt, parseInt, parseInt, parseInt, parseString, parseString,
    parseInt, parseString, parseString, parseString];
38 39
  LogReader.call(this, {
      'code-creation': {
40 41
          parsers: [parseString, parseInt, parseInt, parseInt, parseInt,
              parseString, parseVarArgs],
42 43 44 45 46 47 48
          processor: this.processCodeCreation },
      'code-move': { parsers: [parseInt, parseInt],
          processor: this.processCodeMove },
      'code-delete': { parsers: [parseInt],
          processor: this.processCodeDelete },
      'sfi-move': { parsers: [parseInt, parseInt],
          processor: this.processFunctionMove },
49 50 51 52 53 54
      'LoadGlobalIC': {
        parsers : propertyICParser,
        processor: this.processPropertyIC.bind(this, "LoadGlobalIC") },
      'StoreGlobalIC': {
        parsers : propertyICParser,
        processor: this.processPropertyIC.bind(this, "StoreGlobalIC") },
55 56 57 58 59 60 61 62 63 64 65 66
      'LoadIC': {
        parsers : propertyICParser,
        processor: this.processPropertyIC.bind(this, "LoadIC") },
      'StoreIC': {
        parsers : propertyICParser,
        processor: this.processPropertyIC.bind(this, "StoreIC") },
      'KeyedLoadIC': {
        parsers : propertyICParser,
        processor: this.processPropertyIC.bind(this, "KeyedLoadIC") },
      'KeyedStoreIC': {
        parsers : propertyICParser,
        processor: this.processPropertyIC.bind(this, "KeyedStoreIC") },
67 68 69
      'StoreInArrayLiteralIC': {
        parsers : propertyICParser,
        processor: this.processPropertyIC.bind(this, "StoreInArrayLiteralIC") },
70 71 72
      });
  this.profile_ = new Profile();

73 74
  this.LoadGlobalIC = 0;
  this.StoreGlobalIC = 0;
75 76 77 78
  this.LoadIC = 0;
  this.StoreIC = 0;
  this.KeyedLoadIC = 0;
  this.KeyedStoreIC = 0;
79
  this.StoreInArrayLiteralIC = 0;
80 81 82 83 84 85 86 87 88 89
}
inherits(IcProcessor, LogReader);

/**
 * @override
 */
IcProcessor.prototype.printError = function(str) {
  print(str);
};

90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
IcProcessor.prototype.processString = function(string) {
  var end = string.length;
  var current = 0;
  var next = 0;
  var line;
  var i = 0;
  var entry;
  while (current < end) {
    next = string.indexOf("\n", current);
    if (next === -1) break;
    i++;
    line = string.substring(current, next);
    current = next + 1;
    this.processLogLine(line);
  }
}
106 107

IcProcessor.prototype.processLogFile = function(fileName) {
108
  this.collectEntries = true
109 110 111 112 113 114 115
  this.lastLogFileName_ = fileName;
  var line;
  while (line = readline()) {
    this.processLogLine(line);
  }
  print();
  print("=====================");
116 117
  print("LoadGlobal: " + this.LoadGlobalIC);
  print("StoreGlobal: " + this.StoreGlobalIC);
118 119 120 121
  print("Load: " + this.LoadIC);
  print("Store: " + this.StoreIC);
  print("KeyedLoad: " + this.KeyedLoadIC);
  print("KeyedStore: " + this.KeyedStoreIC);
122
  print("StoreInArrayLiteral: " + this.StoreInArrayLiteralIC);
123 124
};

125 126 127
IcProcessor.prototype.addEntry = function(entry) {
  this.entries.push(entry);
}
128 129

IcProcessor.prototype.processCodeCreation = function(
130
    type, kind, timestamp, start, size, name, maybe_func) {
131 132 133
  if (maybe_func.length) {
    var funcAddr = parseInt(maybe_func[0]);
    var state = parseState(maybe_func[1]);
134
    this.profile_.addFuncCode(type, name, timestamp, start, size, funcAddr, state);
135
  } else {
136
    this.profile_.addCode(type, name, timestamp, start, size);
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
  }
};


IcProcessor.prototype.processCodeMove = function(from, to) {
  this.profile_.moveCode(from, to);
};


IcProcessor.prototype.processCodeDelete = function(start) {
  this.profile_.deleteCode(start);
};


IcProcessor.prototype.processFunctionMove = function(from, to) {
  this.profile_.moveFunc(from, to);
};

IcProcessor.prototype.formatName = function(entry) {
  if (!entry) return "<unknown>"
  var name = entry.func.getName();
  var re = /(.*):[0-9]+:[0-9]+$/;
  var array = re.exec(name);
  if (!array) return name;
161
  return entry.getState() + array[1];
162 163 164
}

IcProcessor.prototype.processPropertyIC = function (
165 166 167 168 169 170 171 172 173
  type, pc, time, line, column, old_state, new_state, map, name, modifier,
  slow_reason) {
this[type]++;
let entry = this.profile_.findEntry(pc);
print(
    type + ' (' + old_state + '->' + new_state + modifier + ') at ' +
    this.formatName(entry) + ':' + line + ':' + column + ' ' + name +
    ' (map 0x' + map.toString(16) + ')' +
    (slow_reason ? ' ' + slow_reason : '') + 'time: ' + time);
174 175 176
}


177

178 179 180 181 182 183 184 185
class ArgumentsProcessor extends BaseArgumentsProcessor {
  getArgsDispatch() {
    return {
      '--range': ['range', 'auto,auto',
          'Specify the range limit as [start],[end]'],
      '--source-map': ['sourceMap', null,
          'Specify the source map that should be used for output']
    };
186
  }
187 188 189 190 191
  getDefaultResults() {
   return {
      logFileName: 'v8.log',
      range: 'auto,auto',
    };
192
  }
193
}