Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,281 @@
// Copyright 2020 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.
import {formatBytes} from '../helper.mjs';
import {LogEntry} from './log.mjs';
class CodeString {
constructor(string) {
if (typeof string !== 'string') {
throw new Error('Expected string');
}
this.string = string;
}
get isCode() {
return true;
}
toString() {
return this.string;
}
}
export class DeoptLogEntry extends LogEntry {
constructor(
type, time, entry, deoptReason, deoptLocation, scriptOffset,
instructionStart, codeSize, inliningId) {
super(type, time);
/** @type {CodeEntry} */
this._entry = entry;
/** @type {string} */
this._reason = deoptReason;
/** @type {SourcePosition} */
this._location = deoptLocation;
/** @type {number} */
this._scriptOffset = scriptOffset;
/** @type {number} */
this._instructionStart = instructionStart;
/** @type {number} */
this._codeSize = codeSize;
/** @type {string} */
this._inliningId = inliningId;
this.fileSourcePosition = undefined;
}
get reason() {
return this._reason;
}
get location() {
return this._location;
}
get entry() {
return this._entry;
}
get code() {
return this._entry?.logEntry;
}
get functionName() {
return this._entry.functionName;
}
static get propertyNames() {
return [
'type', 'reason', 'functionName', 'sourcePosition',
'functionSourcePosition', 'script', 'code'
];
}
}
class CodeLikeLogEntry extends LogEntry {
constructor(type, time, profilerEntry) {
super(type, time);
/** @type {CodeEntry} */
this._entry = profilerEntry;
profilerEntry.logEntry = this;
/** @type {LogEntry[]} */
this._relatedEntries = [];
}
get entry() {
return this._entry;
}
add(entry) {
this._relatedEntries.push(entry);
}
relatedEntries() {
return this._relatedEntries;
}
}
export class CodeLogEntry extends CodeLikeLogEntry {
constructor(type, time, kindName, kind, name, profilerEntry) {
super(type, time, profilerEntry);
this._kind = kind;
/** @type {string} */
this._kindName = kindName;
/** @type {?FeedbackVectorEntry} */
this._feedbackVector = undefined;
/** @type {string} */
this._name = name;
}
get name() {
return this._name;
}
get kind() {
return this._kind;
}
get isBuiltinKind() {
return this._kindName === 'Builtin';
}
get isBytecodeKind() {
return this._kindName === 'Unopt';
}
get isScript() {
return this._type.startsWith('Script');
}
get kindName() {
return this._kindName;
}
get functionName() {
return this._entry.functionName ?? this._entry.getRawName();
}
get shortName() {
if (this.isScript) {
let url = this.sourcePosition?.script?.name ?? '';
return url.substring(url.lastIndexOf('/') + 1);
}
return this.functionName;
}
get size() {
return this._entry.size;
}
get source() {
return this._entry?.getSourceCode() ?? '';
}
get code() {
return this._entry?.source?.disassemble;
}
get variants() {
const entries = Array.from(this.entry?.sfi?.codeEntries ?? []);
return entries.map(each => each.logEntry);
}
get feedbackVector() {
return this._feedbackVector;
}
setFeedbackVector(fbv) {
if (this._feedbackVector) {
throw new Error('Double setting FeedbackVector');
}
this._feedbackVector = fbv;
}
toString() {
return `Code(${this.type})`;
}
get toolTipDict() {
const dict = super.toolTipDict;
dict.size = formatBytes(dict.size);
dict.source = new CodeString(dict.source);
if (dict.code) dict.code = new CodeString(dict.code);
return dict;
}
static get propertyNames() {
return [
'functionName', 'sourcePosition', 'kindName', 'size', 'type', 'kind',
'script', 'source', 'code', 'feedbackVector', 'variants'
];
}
}
export class FeedbackVectorEntry extends LogEntry {
constructor(
timestamp, codeEntry, fbvAddress, length, optimizationMarker,
optimizationTier, invocationCount, profilerTicks, string) {
super('FeedbackVector', timestamp);
this._length = length;
this._code = codeEntry;
this._string = string;
this._optimizationMarker = optimizationMarker;
this._optimizationTier = optimizationTier;
this._invocationCount = invocationCount;
this._profilerTicks = profilerTicks;
}
toString() {
return `FeedbackVector(l=${this.length})`
}
get length() {
return this._length;
}
get code() {
return this._code;
}
get string() {
return this._string;
}
get optimizationMarker() {
return this._optimizationMarker;
}
get optimizationTier() {
return this._optimizationTier;
}
get invocationCount() {
return this._invocationCount;
}
get profilerTicks() {
return this._profilerTicks;
}
static get propertyNames() {
return [
'length', 'length', 'code', 'optimizationMarker', 'optimizationTier',
'invocationCount', 'profilerTicks', 'string'
];
}
}
export class BaseCPPLogEntry extends CodeLikeLogEntry {
constructor(prefix, profilerEntry) {
super(prefix, 0, profilerEntry);
}
get name() {
return this._entry.name;
}
get shortName() {
let name = this.name;
return name.substring(name.lastIndexOf('/') + 1);
}
toString() {
return `SharedLib`;
}
static get propertyNames() {
return ['name'];
}
}
export class CPPCodeLogEntry extends BaseCPPLogEntry {
constructor(profilerEntry) {
super('CPP', profilerEntry);
}
}
export class SharedLibLogEntry extends BaseCPPLogEntry {
constructor(profilerEntry) {
super('SHARED_LIB', profilerEntry);
}
}

View File

@ -0,0 +1,69 @@
// Copyright 2020 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.
import {LogEntry} from './log.mjs';
export class IcLogEntry extends LogEntry {
constructor(
type, fn_file, time, line, column, key, oldState, newState, map, reason,
modifier, codeEntry) {
super(type, time);
this.category = 'other';
if (this.type.indexOf('Store') !== -1) {
this.category = 'Store';
} else if (this.type.indexOf('Load') !== -1) {
this.category = 'Load';
}
const parts = fn_file.split(' ');
this.functionName = parts[0];
this.file = parts[1];
this.oldState = oldState;
this.newState = newState;
this.key = key;
this.map = map;
this.reason = reason;
this.modifier = modifier;
this.codeEntry = codeEntry;
}
get state() {
return this.oldState + ' → ' + this.newState;
}
get code() {
return this.codeEntry?.logEntry;
}
parseMapProperties(parts, offset) {
let next = parts[++offset];
if (!next.startsWith('dict')) return offset;
this.propertiesMode = next.substr(5) == '0' ? 'fast' : 'slow';
this.numberOfOwnProperties = parts[++offset].substr(4);
next = parts[++offset];
this.instanceType = next.substr(5, next.length - 6);
return offset;
}
parsePositionAndFile(parts, start) {
// find the position of 'at' in the parts array.
let offset = start;
for (let i = start + 1; i < parts.length; i++) {
offset++;
if (parts[i] == 'at') break;
}
if (parts[offset] !== 'at') return -1;
this.position = parts.slice(start, offset).join(' ');
offset += 1;
this.isNative = parts[offset] == 'native'
offset += this.isNative ? 1 : 0;
this.file = parts[offset];
return offset;
}
static get propertyNames() {
return [
'type', 'category', 'functionName', 'script', 'sourcePosition', 'code',
'state', 'key', 'map', 'reason'
];
}
}

View File

@ -0,0 +1,59 @@
// Copyright 2020 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.
export class LogEntry {
constructor(type, time) {
/** @type {number} */
this._time = time;
this._type = type;
/** @type {?SourcePosition} */
this.sourcePosition = undefined;
}
get time() {
return this._time;
}
get type() {
return this._type;
}
get script() {
return this.sourcePosition?.script;
}
toString() {
let name = this.constructor.name;
const index = name.lastIndexOf('LogEntry');
if (index > 0) {
name = name.substr(0, index);
}
return `${name}(${this._type})`;
}
get toolTipDict() {
const toolTipDescription = {
__proto__: null,
__this__: this,
title: this.toString()
};
for (let key of this.constructor.propertyNames) {
toolTipDescription[key] = this[key];
}
return toolTipDescription;
}
// Returns an Array of all possible #type values.
/** @return {string[]} */
static get allTypes() {
throw new Error('Not implemented.');
}
// Returns an array of public property names.
/** @return {string[]} */
static get propertyNames() {
throw new Error('Not implemented.');
}
}

View File

@ -0,0 +1,329 @@
// Copyright 2020 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.
import {LogEntry} from './log.mjs';
// ===========================================================================
// Map Log Events
export const kChunkHeight = 200;
export const kChunkWidth = 10;
export const kChunkVisualWidth = 6;
function define(prototype, name, fn) {
Object.defineProperty(prototype, name, {value: fn, enumerable: false});
}
define(Array.prototype, 'max', function(fn) {
if (this.length === 0) return undefined;
if (fn === undefined) fn = (each) => each;
let max = fn(this[0]);
for (let i = 1; i < this.length; i++) {
max = Math.max(max, fn(this[i]));
}
return max;
})
define(Array.prototype, 'first', function() {
return this[0]
});
define(Array.prototype, 'last', function() {
return this[this.length - 1]
});
// ===========================================================================
// Map Log Events
export class MapLogEntry extends LogEntry {
constructor(id, time) {
if (!time) throw new Error('Invalid time');
// Use MapLogEntry.type getter instead of property, since we only know the
// type lazily from the incoming transition.
super(undefined, time);
this.id = id;
MapLogEntry.set(id, this);
this.edge = undefined;
this.children = [];
this.depth = 0;
this._isDeprecated = false;
this.deprecatedTargets = null;
this.leftId = 0;
this.rightId = 0;
this.entry = undefined;
this.description = '';
}
get functionName() {
return this.entry?.functionName;
}
get code() {
return this.entry?.logEntry;
}
toString() {
return `Map(${this.id})`;
}
finalizeRootMap(id) {
let stack = [this];
while (stack.length > 0) {
let current = stack.pop();
if (current.leftId !== 0) {
console.warn('Skipping potential parent loop between maps:', current)
continue;
}
current.finalize(id);
id += 1;
current.children.forEach(edge => stack.push(edge.to));
// TODO implement rightId
}
return id;
}
finalize(id) {
// Initialize preorder tree traversal Ids for fast subtree inclusion checks
if (id <= 0) throw 'invalid id';
let currentId = id;
this.leftId = currentId
}
get parent() {
return this.edge?.from;
}
isDeprecated() {
return this._isDeprecated;
}
deprecate() {
this._isDeprecated = true;
}
isRoot() {
return this.edge === undefined || this.edge.from === undefined;
}
contains(map) {
return this.leftId < map.leftId && map.rightId < this.rightId;
}
addEdge(edge) {
this.children.push(edge);
}
chunkIndex(chunks) {
// Did anybody say O(n)?
for (let i = 0; i < chunks.length; i++) {
let chunk = chunks[i];
if (chunk.isEmpty()) continue;
if (chunk.last().time < this.time) continue;
return i;
}
return -1;
}
position(chunks) {
const index = this.chunkIndex(chunks);
if (index === -1) return [0, 0];
const xFrom = (index * kChunkWidth + kChunkVisualWidth / 2) | 0;
const yFrom = kChunkHeight - chunks[index].yOffset(this) | 0;
return [xFrom, yFrom];
}
transitions() {
let transitions = Object.create(null);
let current = this;
while (current) {
let edge = current.edge;
if (edge && edge.isTransition()) {
transitions[edge.name] = edge;
}
current = current.parent;
}
return transitions;
}
get type() {
return this.edge?.type ?? 'new';
}
get reason() {
return this.edge?.reason;
}
get property() {
return this.edge?.name;
}
isBootstrapped() {
return this.edge === undefined;
}
getParents() {
let parents = [];
let current = this.parent;
while (current) {
parents.push(current);
current = current.parent;
}
return parents;
}
static get(id, time = undefined) {
let maps = this.cache.get(id);
if (maps === undefined) return undefined;
if (time !== undefined) {
for (let i = 1; i < maps.length; i++) {
if (maps[i].time > time) {
return maps[i - 1];
}
}
}
// default return the latest
return maps[maps.length - 1];
}
static set(id, map) {
if (this.cache.has(id)) {
this.cache.get(id).push(map);
} else {
this.cache.set(id, [map]);
}
}
static get propertyNames() {
return [
'type', 'reason', 'property', 'parent', 'functionName', 'sourcePosition',
'script', 'code', 'id', 'description'
];
}
}
MapLogEntry.cache = new Map();
// ===========================================================================
export class Edge {
constructor(type, name, reason, time, from, to) {
this.type = type;
this.name = name;
this.reason = reason;
this.time = time;
this.from = from;
this.to = to;
}
updateFrom(edge) {
if (this.to !== edge.to || this.from !== edge.from) {
throw new Error('Invalid Edge updated', this, to);
}
this.type = edge.type;
this.name = edge.name;
this.reason = edge.reason;
this.time = edge.time;
}
finishSetup() {
const from = this.from;
const to = this.to;
if (to?.time < from?.time) {
// This happens for map deprecation where the transition tree is converted
// in reverse order.
console.warn('Invalid time order');
}
if (from) from.addEdge(this);
if (to === undefined) return;
to.edge = this;
if (from === undefined) return;
if (to === from) throw 'From and to must be distinct.';
let newDepth = from.depth + 1;
if (to.depth > 0 && to.depth != newDepth) {
console.warn('Depth has already been initialized');
}
to.depth = newDepth;
}
chunkIndex(chunks) {
// Did anybody say O(n)?
for (let i = 0; i < chunks.length; i++) {
let chunk = chunks[i];
if (chunk.isEmpty()) continue;
if (chunk.last().time < this.time) continue;
return i;
}
return -1;
}
parentEdge() {
if (!this.from) return undefined;
return this.from.edge;
}
chainLength() {
let length = 0;
let prev = this;
while (prev) {
prev = this.parent;
length++;
}
return length;
}
isTransition() {
return this.type === 'Transition'
}
isFastToSlow() {
return this.type === 'Normalize'
}
isSlowToFast() {
return this.type === 'SlowToFast'
}
isInitial() {
return this.type === 'InitialMap'
}
isBootstrapped() {
return this.type === 'new'
}
isReplaceDescriptors() {
return this.type === 'ReplaceDescriptors'
}
isCopyAsPrototype() {
return this.reason === 'CopyAsPrototype'
}
isOptimizeAsPrototype() {
return this.reason === 'OptimizeAsPrototype'
}
symbol() {
if (this.isTransition()) return '+';
if (this.isFastToSlow()) return '⊡';
if (this.isSlowToFast()) return '⊛';
if (this.isReplaceDescriptors()) {
if (this.name) return '+';
return '∥';
}
return '';
}
toString() {
let s = this.symbol();
if (this.isTransition()) return s + this.name;
if (this.isFastToSlow()) return s + this.reason;
if (this.isCopyAsPrototype()) return s + 'Copy as Prototype';
if (this.isOptimizeAsPrototype()) {
return s + 'Optimize as Prototype';
}
if (this.isReplaceDescriptors() && this.name) {
return this.type + ' ' + this.symbol() + this.name;
}
return this.type + ' ' + (this.reason ? this.reason : '') + ' ' +
(this.name ? this.name : '')
}
}

View File

@ -0,0 +1,62 @@
// Copyright 2021 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.
import {Profile} from '../../profile.mjs'
import {LogEntry} from './log.mjs';
export class TickLogEntry extends LogEntry {
constructor(time, vmState, processedStack) {
super(TickLogEntry.extractType(vmState, processedStack), time);
/** @type {string} */
this.state = vmState;
/** @type {CodeEntry[]} */
this.stack = processedStack;
/** @type {number} */
this._endTime = time;
}
end(time) {
if (this.isInitialized) throw new Error('Invalid timer change');
this._endTime = time;
}
get isInitialized() {
return this._endTime !== this._time;
}
get startTime() {
return this._time;
}
get endTime() {
return this._endTime;
}
get duration() {
return this._endTime - this._time;
}
static extractType(vmState, processedStack) {
if (processedStack.length == 0 || vmState == Profile.VMState.IDLE) {
return 'Idle';
}
const topOfStack = processedStack[0];
if (typeof topOfStack === 'number' || typeof topOfStack === 'bigint') {
// TODO(cbruni): Handle VmStack and native ticks better.
return 'Other';
}
if (vmState != Profile.VMState.JS) {
topOfStack.vmState = vmState;
}
return this.extractCodeEntryType(topOfStack);
}
static extractCodeEntryType(entry) {
if (entry?.state !== undefined) {
return 'JS ' + Profile.getKindFromState(entry.state);
}
if (entry?.vmState) return Profile.vmStateString(entry.vmState);
return 'Other';
}
}

View File

@ -0,0 +1,56 @@
// Copyright 2021 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.
import {formatDurationMicros} from '../helper.mjs';
import {LogEntry} from './log.mjs';
export class TimerLogEntry extends LogEntry {
constructor(type, startTime, endTime = -1) {
super(type, startTime);
this._endTime = endTime;
this.depth = 0;
}
end(time) {
if (this.isInitialized) throw new Error('Invalid timer change');
this._endTime = time;
}
get isInitialized() {
return this._endTime !== -1;
}
get startTime() {
return this._time;
}
get endTime() {
return this._endTime;
}
get duration() {
return Math.max(0, this._endTime - this._time);
}
covers(time) {
return this._time <= time && time <= this._endTime;
}
get toolTipDict() {
const dict = super.toolTipDict;
dict.startTime = formatDurationMicros(dict.startTime);
dict.endTime = formatDurationMicros(dict.endTime);
dict.duration = formatDurationMicros(dict.duration);
return dict;
}
static get propertyNames() {
return [
'type',
'startTime',
'endTime',
'duration',
];
}
}