Skip to content

Commit

Permalink
More trace log improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
wycats committed Nov 13, 2024
1 parent a9717f3 commit 15096e9
Show file tree
Hide file tree
Showing 36 changed files with 592 additions and 183 deletions.
27 changes: 21 additions & 6 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,18 @@
"mode": "auto"
}
],
"eslint.validate": ["javascript", "typescript", "json", "jsonc"],
"eslint.validate": [
"javascript",
"typescript",
"json",
"jsonc"
],
"files.exclude": {
"**/.DS_Store": true,
"**/.git": true
"**/.git": true,
"**/node_modules": true,
"**/dist": true,
"tracerbench-results": true,
},
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true,
Expand All @@ -52,9 +60,15 @@
"eslint.problems.shortenToSingleLine": true,
"typescript.experimental.expandableHover": true,
"inline-bookmarks.expert.custom.words.mapping": {
"warn": ["@premerge(\\s|$)"],
"active": ["@active(\\s|$)"],
"fixme": ["@fixme(\\s|$)"]
"warn": [
"@premerge(\\s|$)"
],
"active": [
"@active(\\s|$)"
],
"fixme": [
"@fixme(\\s|$)"
]
},
"inline-bookmarks.expert.custom.styles": {
"active": {
Expand Down Expand Up @@ -226,5 +240,6 @@
"rewrap.onSave": false,
"rewrap.autoWrap.enabled": true,
"rewrap.reformat": true,
"rewrap.wholeComment": false
"rewrap.wholeComment": false,
"explorer.excludeGitIgnore": true
}
79 changes: 44 additions & 35 deletions bin/setup-bench.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { readFile, writeFile } from 'node:fs/promises';
const ROOT = new URL('..', import.meta.url).pathname;
$.verbose = true;

const REUSE_CONTROL = !!process.env['REUSE_CONTROL'];
const REUSE_CONTROL = !!(process.env['REUSE_DIRS'] || process.env['REUSE_CONTROL']);
const REUSE_EXPERIMENT = !!(process.env['REUSE_DIRS'] || process.env['REUSE_EXPERIMENT']);

/*
Expand Down Expand Up @@ -81,8 +82,10 @@ if (!REUSE_CONTROL) {
await $`mkdir ${CONTROL_DIR}`;
}

await $`rm -rf ${EXPERIMENT_DIR}`;
await $`mkdir ${EXPERIMENT_DIR}`;
if (!REUSE_EXPERIMENT) {
await $`rm -rf ${EXPERIMENT_DIR}`;
await $`mkdir ${EXPERIMENT_DIR}`;
}

// Intentionally use the same folder for both experiment and control to make it easier to
// make changes to the benchmark suite itself and compare the results.
Expand Down Expand Up @@ -138,16 +141,10 @@ console.info({
});

// setup experiment
await within(async () => {
await buildRepo(EXPERIMENT_DIR, experimentRef);
});
await buildRepo(EXPERIMENT_DIR, experimentRef, REUSE_EXPERIMENT);

if (!REUSE_CONTROL) {
// setup control
await within(async () => {
await buildRepo(CONTROL_DIR, controlRef);
});
}
// setup control
await buildRepo(CONTROL_DIR, controlRef, REUSE_CONTROL);

// start build assets
$`cd ${CONTROL_BENCH_DIR} && pnpm vite preview --port ${CONTROL_PORT}`;
Expand Down Expand Up @@ -177,36 +174,48 @@ process.exit(0);
/**
* @param {string} directory the directory to clone into
* @param {string} ref the ref to checkout
* @param {boolean} reuse reuse the existing directory
*/
async function buildRepo(directory, ref) {
// the benchmark directory is located in `packages/@glimmer/benchmark` in each of the
// experiment and control checkouts
const benchDir = join(directory, 'benchmark', 'benchmarks', 'krausest');
async function buildRepo(directory, ref, reuse) {
if (!reuse) {
await $`rm -rf ${directory}`;
await $`mkdir ${directory}`;
}

await cd(directory);
await within(async () => {
// the benchmark directory is located in `packages/@glimmer/benchmark` in each of the
// experiment and control checkouts
const benchDir = join(directory, 'benchmark', 'benchmarks', 'krausest');

// write the `pwd` to the output to make it easier to debug if something goes wrong
await $`pwd`;
await cd(directory);

// clone the raw git repo for the experiment
await $`git clone ${join(ROOT, '.git')} .`;
// write the `pwd` to the output to make it easier to debug if something goes wrong
await $`pwd`;

// checkout the repo to the HEAD of the current branch
await $`git checkout --force ${ref}`;
if (reuse) {
await $`git fetch`;
} else {
// clone the raw git repo for the experiment
await $`git clone ${join(ROOT, '.git')} .`;
}

// recreate the benchmark directory
await $`rm -rf ./benchmark`;
// intentionally use the same folder for both experiment and control
await $`cp -r ${BENCHMARK_FOLDER} ./benchmark`;
// checkout the repo to the HEAD of the current branch
await $`git checkout --force ${ref}`;

// `pnpm install` and build the repo
await $`pnpm install --no-frozen-lockfile`;
await $`pnpm build`;
// recreate the benchmark directory
await $`rm -rf ./benchmark`;
// intentionally use the same folder for both experiment and control
await $`cp -r ${BENCHMARK_FOLDER} ./benchmark`;

// rewrite all `package.json`s to behave like published packages
await rewritePackageJson();
// `pnpm install` and build the repo
await $`pnpm install --no-frozen-lockfile`;
await $`pnpm build`;

// build the benchmarks using vite
await cd(benchDir);
await $`pnpm vite build`;
// rewrite all `package.json`s to behave like published packages
await rewritePackageJson();

// build the benchmarks using vite
await cd(benchDir);
await $`pnpm vite build`;
});
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
"tracerbench": "^8.0.1",
"ts-node": "^10.9.1",
"turbo": "^1.9.3",
"typescript": "^5.0.4",
"typescript": "~5.0.4",
"vite": "^5.4.10",
"xo": "^0.54.2",
"zx": "^8.1.9"
Expand Down
11 changes: 10 additions & 1 deletion packages/@glimmer-workspace/integration-tests/lib/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import type { CapturedArguments, Dict } from '@glimmer/interfaces';
import type { Reference } from '@glimmer/reference';
import { setLocalDebugType } from '@glimmer/debug-util';
import { LOCAL_DEBUG } from '@glimmer/local-debug-flags';
import { createComputeRef } from '@glimmer/reference';
import { reifyNamed, reifyPositional } from '@glimmer/runtime';

export type UserHelper = (args: ReadonlyArray<unknown>, named: Dict<unknown>) => unknown;

export function createHelperRef(helper: UserHelper, args: CapturedArguments): Reference {
return createComputeRef(() => helper(reifyPositional(args.positional), reifyNamed(args.named)));
return createComputeRef(
() => helper(reifyPositional(args.positional), reifyNamed(args.named)),
undefined
);
}

if (LOCAL_DEBUG) {
setLocalDebugType('factory:helper', createHelperRef, { name: 'createHelper' });
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Dict, Nullable, SimpleElement } from '@glimmer/interfaces';
import { COMMENT_NODE, ELEMENT_NODE } from '@glimmer/constants';
import { castToBrowser, castToSimple, expect } from '@glimmer/debug-util';
import { isObject, LOCAL_LOGGER } from '@glimmer/util';
import { isIndexable, LOCAL_LOGGER } from '@glimmer/util';

import type { ComponentBlueprint, Content } from '..';

Expand Down Expand Up @@ -165,7 +165,7 @@ abstract class AbstractChaosMonkeyTest extends RenderTest {
}

function getErrorMessage(assert: Assert, error: unknown): string {
if (isObject(error) && 'message' in error && typeof error.message === 'string') {
if (isIndexable(error) && 'message' in error && typeof error.message === 'string') {
return error.message;
} else {
assert.pushResult({
Expand Down
21 changes: 17 additions & 4 deletions packages/@glimmer/compiler/lib/passes/1-normalization/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ASTv2, src } from '@glimmer/syntax';
import { DebugLogger, frag, fragment, valueFragment } from '@glimmer/debug';
import { LOCAL_TRACE_LOGGING } from '@glimmer/local-debug-flags';
import { LOCAL_LOGGER } from '@glimmer/util';

Expand Down Expand Up @@ -56,16 +57,28 @@ export default function normalize(
let state = new NormalizationState(root.table, isStrict);

if (LOCAL_TRACE_LOGGING) {
LOCAL_LOGGER.groupCollapsed(`pass0: visiting`);
LOCAL_LOGGER.debug('symbols', root.table);
LOCAL_LOGGER.debug('source', source);
LOCAL_LOGGER.groupEnd();
const logger = DebugLogger.configured();
const done = logger.group(`pass0: visiting`).collapsed();
logger.log(valueFragment(root.table));
// LOCAL_LOGGER.debug('symbols', root.table);
logger.log(valueFragment(source));
done();
}

let body = VISIT_STMTS.visitList(root.body, state);

if (LOCAL_TRACE_LOGGING) {
const logger = DebugLogger.configured();

if (body.isOk) {
const done = logger.group(frag`pass0: out`).collapsed();
const ops = body.value.toPresentArray();

if (ops) {
const full = frag` ${valueFragment(ops)}`.subtle();
logger.log(frag`${fragment.array(ops.map((op) => valueFragment(op)))}${full}`);
}
done();
LOCAL_LOGGER.debug('-> pass0: out', body.value);
} else {
LOCAL_LOGGER.debug('-> pass0: error', body.reason);
Expand Down
1 change: 1 addition & 0 deletions packages/@glimmer/compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"devDependencies": {
"@glimmer-workspace/build-support": "workspace:*",
"@glimmer/constants": "workspace:*",
"@glimmer/debug": "workspace:*",
"@glimmer/debug-util": "workspace:*",
"@glimmer/local-debug-flags": "workspace:*",
"@types/node": "^20.9.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/@glimmer/debug-util/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as assert, assertNever, deprecate } from './lib/assert';
export * from './lib/debug-brand';
export { default as debugToString } from './lib/debug-to-string';
export * from './lib/platform-utils';
export * from './lib/present';
Expand All @@ -11,5 +12,4 @@ export {
} from './lib/simple-cast';
export * from './lib/template';
export { default as buildUntouchableThis } from './lib/untouchable-this';

export type FIXME<T, S extends string> = (T & S) | T;
118 changes: 118 additions & 0 deletions packages/@glimmer/debug-util/lib/debug-brand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import type {
AnyFn,
AppendingBlock,
BlockArguments,
Cursor,
Dict,
NamedArguments,
PositionalArguments,
VMArguments,
} from '@glimmer/interfaces';
import { LOCAL_DEBUG } from '@glimmer/local-debug-flags';

const LOCAL_DEBUG_BRAND = new WeakMap<object, ClassifiedLocalDebug>();

/**
* An object branded with a local debug type has special local trace logging
* behavior.
*
* If `LOCAL_DEBUG` is `false`, this function does nothing (and is removed
* by the minifier in builder).
*/
export function setLocalDebugType<P extends LocalDebugType>(
type: P,
...brand: SetLocalDebugArgs<P>
): void;
export function setLocalDebugType(type: string, ...brand: [value: object, options?: object]) {
if (LOCAL_DEBUG) {
if (brand.length === 1) {
const [value] = brand;
LOCAL_DEBUG_BRAND.set(value, { type, value } as ClassifiedLocalDebug);
} else {
const [value, options] = brand;
LOCAL_DEBUG_BRAND.set(value, { type, value, options } as ClassifiedLocalDebug);
}
}
}

/**
* An object branded with a local debug type has special local trace logging
* behavior.
*
* If `LOCAL_DEBUG` is `false`, this function always returns undefined. However,
* this function should only be called by the trace logger, which should only
* run in trace `LOCAL_DEBUG` + `LOCAL_TRACE_LOGGING` mode.
*/
export function getLocalDebugType(value: object): ClassifiedLocalDebug | void {
if (LOCAL_DEBUG) {
return LOCAL_DEBUG_BRAND.get(value);
}
}

interface SourcePosition {
line: number;
column: number;
}

export interface LocalDebugMap {
args: [VMArguments];
'args:positional': [PositionalArguments];
'args:named': [NamedArguments];
'args:blocks': [BlockArguments];
cursor: [Cursor];
'block:simple': [AppendingBlock];
'block:remote': [AppendingBlock];
'block:resettable': [AppendingBlock];
'factory:helper': [AnyFn, { name: string }];

'syntax:source': [{ readonly source: string; readonly module: string }];
'syntax:symbol-table:program': [object, { debug?: () => DebugProgramSymbolTable }];

'syntax:mir:node': [
{ loc: { startPosition: SourcePosition; endPosition: SourcePosition }; type: string },
];
}

export interface DebugProgramSymbolTable {
readonly templateLocals: readonly string[];
readonly keywords: readonly string[];
readonly symbols: readonly string[];
readonly upvars: readonly string[];
readonly named: Dict<number>;
readonly blocks: Dict<number>;
readonly hasDebugger: boolean;
}

export type LocalDebugType = keyof LocalDebugMap;

export type SetLocalDebugArgs<D extends LocalDebugType> = {
[P in D]: LocalDebugMap[P] extends [infer This extends object, infer Options extends object]
? [This, Options]
: LocalDebugMap[P] extends [infer This extends object]
? [This]
: never;
}[D];

export type ClassifiedLocalDebug = {
[P in LocalDebugType]: LocalDebugMap[P] extends [infer T, infer Options]
? { type: P; value: T; options: Options }
: LocalDebugMap[P] extends [infer T]
? { type: P; value: T }
: never;
}[LocalDebugType];

export type ClassifiedLocalDebugFor<N extends LocalDebugType> = LocalDebugMap[N] extends [
infer T,
infer Options,
]
? { type: N; value: T; options: Options }
: LocalDebugMap[N] extends [infer T]
? { type: N; value: T }
: never;

export type ClassifiedOptions<N extends LocalDebugType> = LocalDebugMap[N] extends [
unknown,
infer Options,
]
? Options
: never;
Loading

0 comments on commit 15096e9

Please sign in to comment.