1<!DOCTYPE html>
2<!--
3Copyright 2015 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/model/source_info/js_source_info.html">
9
10<script>
11'use strict';
12
13/**
14 * @fileoverview TraceCodeEntry is a wrapper around the V8 CodeEntry that
15 * extracts extra context information for each item. This includes things like
16 * the source file, line and if the function is a native method or not.
17 */
18tr.exportTo('tr.e.importer', function() {
19  function TraceCodeEntry(address, size, name, scriptId) {
20    this.id_ = tr.b.GUID.allocate();
21    this.address_ = address;
22    this.size_ = size;
23
24    // Stolen from DevTools TimelineJSProfileProcessor._buildCallFrame
25    // Code states:
26    // (empty) -> compiled
27    //    ~    -> optimizable
28    //    *    -> optimized
29    var rePrefix = /^(\w*:)?([*~]?)(.*)$/m;
30    var tokens = rePrefix.exec(name);
31    var prefix = tokens[1];
32    var state = tokens[2];
33    var body = tokens[3];
34
35    if (state === '*') {
36      state = tr.model.source_info.JSSourceState.OPTIMIZED;
37    } else if (state === '~') {
38      state = tr.model.source_info.JSSourceState.OPTIMIZABLE;
39    } else if (state === '') {
40      state = tr.model.source_info.JSSourceState.COMPILED;
41    } else {
42      console.warning('Unknown v8 code state ' + state);
43      state = tr.model.source_info.JSSourceState.UNKNOWN;
44    }
45
46    var rawName;
47    var rawUrl;
48    if (prefix === 'Script:') {
49        rawName = '';
50        rawUrl = body;
51    } else {
52        var spacePos = body.lastIndexOf(' ');
53        rawName = spacePos !== -1 ? body.substr(0, spacePos) : body;
54        rawUrl = spacePos !== -1 ? body.substr(spacePos + 1) : '';
55    }
56
57    function splitLineAndColumn(url) {
58      var lineColumnRegEx = /(?::(\d+))?(?::(\d+))?$/;
59      var lineColumnMatch = lineColumnRegEx.exec(url);
60      var lineNumber;
61      var columnNumber;
62
63      if (typeof(lineColumnMatch[1]) === 'string') {
64        lineNumber = parseInt(lineColumnMatch[1], 10);
65        // Immediately convert line and column to 0-based numbers.
66        lineNumber = isNaN(lineNumber) ? undefined : lineNumber - 1;
67      }
68      if (typeof(lineColumnMatch[2]) === 'string') {
69        columnNumber = parseInt(lineColumnMatch[2], 10);
70        columnNumber = isNaN(columnNumber) ? undefined : columnNumber - 1;
71      }
72
73      return {
74        url: url.substring(0, url.length - lineColumnMatch[0].length),
75        lineNumber: lineNumber,
76        columnNumber: columnNumber
77      };
78    }
79
80    var nativeSuffix = ' native';
81    var isNative = rawName.endsWith(nativeSuffix);
82    this.name_ =
83        isNative ? rawName.slice(0, -nativeSuffix.length) : rawName;
84
85    var urlData = splitLineAndColumn(rawUrl);
86    var url = urlData.url || '';
87    var line = urlData.lineNumber || 0;
88    var column = urlData.columnNumber || 0;
89
90    this.sourceInfo_ = new tr.model.source_info.JSSourceInfo(
91        url, line, column, isNative, scriptId, state);
92  };
93
94  TraceCodeEntry.prototype = {
95    get id() {
96      return this.id_;
97    },
98
99    get sourceInfo() {
100      return this.sourceInfo_;
101    },
102
103    get name() {
104      return this.name_;
105    },
106
107    set address(address) {
108      this.address_ = address;
109    },
110
111    get address() {
112      return this.address_;
113    },
114
115    set size(size) {
116      this.size_ = size;
117    },
118
119    get size() {
120      return this.size_;
121    }
122  };
123
124  return {
125    TraceCodeEntry: TraceCodeEntry
126  };
127});
128</script>
129
130