Commit d5d45c61 authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[tools] Migrate more tools to ES6 classes

For simplicity this CL includes a first crude conversion of
tickprocessor.mjs. Later CLs will introduce more ES6 syntax and clean
up more code.

Bug: v8:10667
Change-Id: Ief2ca623f5562114fb976a95d156e2ab3f961114
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2611252Reviewed-by: 's avatarSathya Gunasekaran  <gsathya@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72013}
parent 73875e95
......@@ -36,49 +36,47 @@
*
* @constructor
*/
export function ConsArray() {
this.tail_ = new ConsArray.Cell(null, null);
export class ConsArray {
constructor() {
this.tail_ = new ConsArrayCell(null, null);
this.currCell_ = this.tail_;
this.currCellPos_ = 0;
};
/**
}
/**
* Concatenates another array for iterating. Empty arrays are ignored.
* This operation can be safely performed during ongoing ConsArray
* iteration.
*
* @param {Array} arr Array to concatenate.
*/
ConsArray.prototype.concat = function(arr) {
concat(arr) {
if (arr.length > 0) {
this.tail_.data = arr;
this.tail_ = this.tail_.next = new ConsArray.Cell(null, null);
this.tail_ = this.tail_.next = new ConsArrayCell(null, null);
}
}
};
/**
/**
* Whether the end of iteration is reached.
*/
ConsArray.prototype.atEnd = function() {
atEnd() {
return this.currCell_ === null ||
this.currCell_.data === null ||
this.currCellPos_ >= this.currCell_.data.length;
};
}
/**
/**
* Returns the current item, moves to the next one.
*/
ConsArray.prototype.next = function() {
next() {
const result = this.currCell_.data[this.currCellPos_++];
if (this.currCellPos_ >= this.currCell_.data.length) {
this.currCell_ = this.currCell_.next;
this.currCellPos_ = 0;
}
return result;
};
}
}
/**
......@@ -86,7 +84,9 @@ ConsArray.prototype.next = function() {
*
* @constructor
*/
ConsArray.Cell = function(data, next) {
class ConsArrayCell {
constructor(data, next) {
this.data = data;
this.next = next;
};
}
}
......@@ -8,7 +8,6 @@ export {
ArgumentsProcessor, UnixCppEntriesProvider,
WindowsCppEntriesProvider, MacCppEntriesProvider,
} from "./tickprocessor.mjs";
import { inherits } from "./tickprocessor.mjs";
export class CppProcessor extends LogReader {
......@@ -29,7 +28,7 @@ export class CppProcessor extends LogReader {
*/
printError(str) {
print(str);
};
}
processLogFile(fileName) {
this.lastLogFileName_ = fileName;
......@@ -37,14 +36,14 @@ export class CppProcessor extends LogReader {
while (line = readline()) {
this.processLogLine(line);
}
};
}
processLogFileInTest(fileName) {
// Hack file name to avoid dealing with platform specifics.
this.lastLogFileName_ = 'v8.log';
const contents = readFile(fileName);
this.processLogChunk(contents);
};
}
processSharedLibrary(name, startAddr, endAddr, aslrSlide) {
const self = this;
......@@ -53,7 +52,7 @@ export class CppProcessor extends LogReader {
const entry = new CodeEntry(fEnd - fStart, fName, 'CPP');
self.codeMap_.addStaticCode(fStart, entry);
});
};
}
dumpCppSymbols() {
const staticEntries = this.codeMap_.getAllStaticEntriesWithAddresses();
......
......@@ -28,9 +28,13 @@
/**
* @fileoverview Log Reader is used to process log file produced by V8.
*/
import { CsvParser } from "./csvparser.mjs";
// Parses dummy variable for readability;
export const parseString = 'parse-string';
export const parseVarArgs = 'parse-var-args';
/**
* Base class for processing log files.
*
......@@ -41,7 +45,8 @@
* markers.
* @constructor
*/
export function LogReader(dispatchTable, timedRange, pairwiseTimedRange) {
export class LogReader {
constructor (dispatchTable, timedRange, pairwiseTimedRange) {
/**
* @type {Array.<Object>}
*/
......@@ -83,35 +88,32 @@ export function LogReader(dispatchTable, timedRange, pairwiseTimedRange) {
* @type {Array.<String>}
*/
this.logLinesSinceLastTimerMarker_ = [];
};
}
/**
/**
* Used for printing error messages.
*
* @param {string} str Error message.
*/
LogReader.prototype.printError = function(str) {
printError(str) {
// Do nothing.
};
}
/**
/**
* Processes a portion of V8 profiler event log.
*
* @param {string} chunk A portion of log.
*/
LogReader.prototype.processLogChunk = function(chunk) {
processLogChunk(chunk) {
this.processLog_(chunk.split('\n'));
};
}
/**
/**
* Processes a line of V8 profiler event log.
*
* @param {string} line A line of log.
*/
LogReader.prototype.processLogLine = function(line) {
processLogLine(line) {
if (!this.timedRange_) {
this.processLogLine_(line);
return;
......@@ -134,10 +136,9 @@ LogReader.prototype.processLogLine = function(line) {
this.processLogLine_(line);
}
}
};
}
/**
/**
* Processes stack record.
*
* @param {number} pc Program counter.
......@@ -145,7 +146,7 @@ LogReader.prototype.processLogLine = function(line) {
* @param {Array.<string>} stack String representation of a stack.
* @return {Array.<number>} Processed stack.
*/
LogReader.prototype.processStack = function(pc, func, stack) {
processStack(pc, func, stack) {
const fullStack = func ? [pc, func] : [pc];
let prevFrame = pc;
for (let i = 0, n = stack.length; i < n; ++i) {
......@@ -163,28 +164,25 @@ LogReader.prototype.processStack = function(pc, func, stack) {
}
}
return fullStack;
};
}
/**
/**
* Returns whether a particular dispatch must be skipped.
*
* @param {!Object} dispatch Dispatch record.
* @return {boolean} True if dispatch must be skipped.
*/
LogReader.prototype.skipDispatch = dispatch => false;
// Parses dummy variable for readability;
export const parseString = 'parse-string';
export const parseVarArgs = 'parse-var-args';
skipDispatch(dispatch) {
return false;
}
/**
/**
* Does a dispatch of a log record.
*
* @param {Array.<string>} fields Log record.
* @private
*/
LogReader.prototype.dispatchLogRow_ = function(fields) {
dispatchLogRow_(fields) {
// Obtain the dispatch.
const command = fields[0];
const dispatch = this.dispatchTable_[command];
......@@ -212,28 +210,27 @@ LogReader.prototype.dispatchLogRow_ = function(fields) {
// Run the processor.
dispatch.processor.apply(this, parsedFields);
};
}
/**
/**
* Processes log lines.
*
* @param {Array.<string>} lines Log lines.
* @private
*/
LogReader.prototype.processLog_ = function(lines) {
processLog_(lines) {
for (let i = 0, n = lines.length; i < n; ++i) {
this.processLogLine_(lines[i]);
}
}
}
/**
/**
* Processes a single log line.
*
* @param {String} a log line
* @private
*/
LogReader.prototype.processLogLine_ = function(line) {
processLogLine_(line) {
if (line.length > 0) {
try {
const fields = this.csvParser_.parseLine(line);
......@@ -243,4 +240,5 @@ LogReader.prototype.processLogLine_ = function(line) {
}
}
this.lineNum_++;
};
}
}
......@@ -34,29 +34,25 @@
*
* @constructor
*/
export function SplayTree() {
};
export class SplayTree {
/**
/**
* Pointer to the root node of the tree.
*
* @type {SplayTree.Node}
* @type {SplayTreeNode}
* @private
*/
SplayTree.prototype.root_ = null;
root_ = null;
/**
/**
* @return {boolean} Whether the tree is empty.
*/
SplayTree.prototype.isEmpty = function() {
isEmpty() {
return !this.root_;
};
}
/**
/**
* Inserts a node into the tree with the specified key and value if
* the tree does not already contain a node with the specified key. If
* the value is inserted, it becomes the root of the tree.
......@@ -64,18 +60,17 @@ SplayTree.prototype.isEmpty = function() {
* @param {number} key Key to insert into the tree.
* @param {*} value Value to insert into the tree.
*/
SplayTree.prototype.insert = function(key, value) {
insert(key, value) {
if (this.isEmpty()) {
this.root_ = new SplayTree.Node(key, value);
this.root_ = new SplayTreeNode(key, value);
return;
}
// Splay on the key to move the last node on the search path for
// the key to the root of the tree.
this.splay_(key);
if (this.root_.key == key) {
return;
}
const node = new SplayTree.Node(key, value);
if (this.root_.key == key) return;
const node = new SplayTreeNode(key, value);
if (key > this.root_.key) {
node.left = this.root_;
node.right = this.root_.right;
......@@ -86,18 +81,17 @@ SplayTree.prototype.insert = function(key, value) {
this.root_.left = null;
}
this.root_ = node;
};
}
/**
/**
* Removes a node with the specified key from the tree if the tree
* contains a node with this key. The removed node is returned. If the
* key is not found, an exception is thrown.
*
* @param {number} key Key to find and remove from the tree.
* @return {SplayTree.Node} The removed node.
* @return {SplayTreeNode} The removed node.
*/
SplayTree.prototype.remove = function(key) {
remove(key) {
if (this.isEmpty()) {
throw Error(`Key not found: ${key}`);
}
......@@ -118,63 +112,51 @@ SplayTree.prototype.remove = function(key) {
this.root_.right = right;
}
return removed;
};
}
/**
/**
* Returns the node having the specified key or null if the tree doesn't contain
* a node with the specified key.
*
* @param {number} key Key to find in the tree.
* @return {SplayTree.Node} Node having the specified key.
* @return {SplayTreeNode} Node having the specified key.
*/
SplayTree.prototype.find = function(key) {
if (this.isEmpty()) {
return null;
}
find(key) {
if (this.isEmpty()) return null;
this.splay_(key);
return this.root_.key == key ? this.root_ : null;
};
}
/**
* @return {SplayTree.Node} Node having the minimum key value.
/**
* @return {SplayTreeNode} Node having the minimum key value.
*/
SplayTree.prototype.findMin = function() {
if (this.isEmpty()) {
return null;
}
findMin() {
if (this.isEmpty()) return null;
let current = this.root_;
while (current.left) {
current = current.left;
}
return current;
};
}
/**
* @return {SplayTree.Node} Node having the maximum key value.
/**
* @return {SplayTreeNode} Node having the maximum key value.
*/
SplayTree.prototype.findMax = function(opt_startNode) {
if (this.isEmpty()) {
return null;
}
findMax(opt_startNode) {
if (this.isEmpty()) return null;
let current = opt_startNode || this.root_;
while (current.right) {
current = current.right;
}
return current;
};
}
/**
* @return {SplayTree.Node} Node having the maximum key value that
/**
* @return {SplayTreeNode} Node having the maximum key value that
* is less or equal to the specified key value.
*/
SplayTree.prototype.findGreatestLessThan = function(key) {
if (this.isEmpty()) {
return null;
}
findGreatestLessThan(key) {
if (this.isEmpty()) return null;
// Splay on the key to move the node with the given key or the last
// node on the search path to the top of the tree.
this.splay_(key);
......@@ -187,31 +169,28 @@ SplayTree.prototype.findGreatestLessThan = function(key) {
} else {
return null;
}
};
}
/**
/**
* @return {Array<*>} An array containing all the values of tree's nodes paired
* with keys.
*/
SplayTree.prototype.exportKeysAndValues = function() {
exportKeysAndValues() {
const result = [];
this.traverse_(function(node) { result.push([node.key, node.value]); });
return result;
};
}
/**
/**
* @return {Array<*>} An array containing all the values of tree's nodes.
*/
SplayTree.prototype.exportValues = function() {
exportValues() {
const result = [];
this.traverse_(function(node) { result.push(node.value); });
return result;
};
}
/**
/**
* Perform the splay operation for the given key. Moves the node with
* the given key to the top of the tree. If no node has the given
* key, the last node on the search path is moved to the top of the
......@@ -221,17 +200,15 @@ SplayTree.prototype.exportValues = function() {
* @param {number} key Key to splay the tree on.
* @private
*/
SplayTree.prototype.splay_ = function(key) {
if (this.isEmpty()) {
return;
}
splay_(key) {
if (this.isEmpty()) return;
// Create a dummy node. The use of the dummy node is a bit
// counter-intuitive: The right child of the dummy node will hold
// the L tree of the algorithm. The left child of the dummy node
// will hold the R tree of the algorithm. Using a dummy node, left
// and right will always be nodes and we avoid special cases.
let dummy, left, right;
dummy = left = right = new SplayTree.Node(null, null);
dummy = left = right = new SplayTreeNode(null, null);
let current = this.root_;
while (true) {
if (key < current.key) {
......@@ -280,16 +257,15 @@ SplayTree.prototype.splay_ = function(key) {
current.left = dummy.right;
current.right = dummy.left;
this.root_ = current;
};
}
/**
/**
* Performs a preorder traversal of the tree.
*
* @param {function(SplayTree.Node)} f Visitor function.
* @param {function(SplayTreeNode)} f Visitor function.
* @private
*/
SplayTree.prototype.traverse_ = function(f) {
traverse_(f) {
const nodesToVisit = [this.root_];
while (nodesToVisit.length > 0) {
const node = nodesToVisit.shift();
......@@ -300,8 +276,8 @@ SplayTree.prototype.traverse_ = function(f) {
nodesToVisit.push(node.left);
nodesToVisit.push(node.right);
}
};
}
}
/**
* Constructs a Splay tree node.
......@@ -309,19 +285,17 @@ SplayTree.prototype.traverse_ = function(f) {
* @param {number} key Key.
* @param {*} value Value.
*/
SplayTree.Node = function(key, value) {
class SplayTreeNode {
constructor(key, value) {
this.key = key;
this.value = value;
};
/**
* @type {SplayTree.Node}
/**
* @type {SplayTreeNode}
*/
SplayTree.Node.prototype.left = null;
/**
* @type {SplayTree.Node}
this.left = null;
/**
* @type {SplayTreeNode}
*/
SplayTree.Node.prototype.right = null;
this.right = null;
}
};
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment