Skip to content

Commit

Permalink
feat: opt gc cost
Browse files Browse the repository at this point in the history
  • Loading branch information
Sway007 committed Jul 12, 2024
1 parent a730793 commit 1d13f40
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 146 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { IPoolElement } from "@galacean/engine";

type Constructor<T> = new (...args: any[]) => T;
export type Constructor<T> = new (...args: any[]) => T;

export interface IInitializedPoolElement<T, C extends Constructor<T>> {
init(...args: ConstructorParameters<C>): void;
}

export const AstNodePoolSet: AstNodePool<any, any>[] = [];
export const AstNodePoolSet: ObjectPool<any, any>[] = [];
export function clearAllAstNodePool() {
for (let i = 0; i < AstNodePoolSet.length; i++) {
AstNodePoolSet[i].clear();
}
}

export class AstNodePool<C extends Constructor<T>, T extends IPoolElement & IInitializedPoolElement<T, C>> {
export class ObjectPool<C extends Constructor<T>, T extends IPoolElement & IInitializedPoolElement<T, C>> {
private _type: C;
private _elements: T[];
private _usedElementCount: number = -1;
Expand Down
4 changes: 2 additions & 2 deletions packages/shader-lab/src/ShaderLab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ShaderContentParser } from "./contentParser";
// @ts-ignore
import { ClearableObjectPool, Logger, ShaderLib, ShaderMacro, ShaderPlatformTarget } from "@galacean/engine";
import { ShaderPosition, ShaderRange } from "./common";
import { clearAllAstNodePool } from "./AstNodePool";
import { clearAllAstNodePool } from "./ObjectPool";

export class ShaderLab implements IShaderLab {
/**
Expand Down Expand Up @@ -55,6 +55,7 @@ export class ShaderLab implements IShaderLab {
backend: ShaderPlatformTarget,
platformMacros: string[]
) {
clearAllAstNodePool();
Preprocessor.reset(ShaderLib);
for (const macro of macros) {
Preprocessor.addPredefinedMacro(macro.name, macro.value);
Expand All @@ -77,7 +78,6 @@ export class ShaderLab implements IShaderLab {

const lexer = new Lexer(ppdContent);
const tokens = lexer.tokenize();
clearAllAstNodePool();
const program = ShaderLab._parser.parse(tokens);
const codeGen =
backend === ShaderPlatformTarget.GLES100 ? GLES100Visitor.getVisitor() : GLES300Visitor.getVisitor();
Expand Down
16 changes: 13 additions & 3 deletions packages/shader-lab/src/common/BaseToken.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
import { ETokenType } from "./types";
import { ShaderRange, ShaderPosition } from ".";
import { ShaderLab } from "../ShaderLab";
import { ObjectPool, Constructor } from "../ObjectPool";

export class BaseToken<T extends number = number> {
readonly type: T;
readonly lexeme: string;
readonly location: ShaderRange;
static pool = new ObjectPool<Constructor<BaseToken>, BaseToken>(BaseToken, 100);

type: T;
lexeme: string;
location: ShaderRange;

constructor(type: T, lexeme: string, start?: ShaderPosition);
constructor(type: T, lexeme: string, location?: ShaderRange);
constructor(type: T, lexeme: string, arg?: ShaderRange | ShaderPosition) {
// @ts-ignore
this.init(type, lexeme, arg);
}

init(type: T, lexeme: string, start?: ShaderPosition);
init(type: T, lexeme: string, location?: ShaderRange);
init(type: T, lexeme: string, arg?: ShaderRange | ShaderPosition) {
this.type = type;
this.lexeme = lexeme;
if (arg) {
Expand Down
4 changes: 2 additions & 2 deletions packages/shader-lab/src/lalr/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ENonTerminal, GrammarSymbol } from "../parser/GrammarSymbol";
import Production from "./Production";
import { ActionInfo, EAction } from "./types";
import { ShaderLab } from "../ShaderLab";
import { AstNodePool } from "../AstNodePool";
import { ObjectPool } from "../ObjectPool";

export default class GrammarUtils {
static isTerminal(sm: GrammarSymbol) {
Expand All @@ -25,7 +25,7 @@ export default class GrammarUtils {
options: GrammarSymbol[][],
/** the ast node */
// astType?: ASTNodeConstructor
astTypePool?: AstNodePool<ASTNodeConstructor, any>
astTypePool?: ObjectPool<ASTNodeConstructor, any>
) {
const ret: [GrammarSymbol[], TranslationRule | undefined][] = [];
for (const opt of options) {
Expand Down
128 changes: 76 additions & 52 deletions packages/shader-lab/src/lexer/Lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,164 +43,182 @@ export class Lexer extends BaseScanner {
this.advance();
if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.LEFT_ASSIGN, "<<=", start);
return BaseToken.pool.get(ETokenType.LEFT_ASSIGN, "<<=", start);
}
return new BaseToken(ETokenType.LEFT_OP, "<<", start);
return BaseToken.pool.get(ETokenType.LEFT_OP, "<<", start);
} else if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.LE_OP, "<=", start);
return BaseToken.pool.get(ETokenType.LE_OP, "<=", start);
}
return new BaseToken(ETokenType.LEFT_ANGLE, "<", start);
return BaseToken.pool.get(ETokenType.LEFT_ANGLE, "<", start);

case ">":
this.advance();
if (this.getCurChar() === ">") {
this.advance();
if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.RIGHT_ASSIGN, ">>=", start);
return BaseToken.pool.get(ETokenType.RIGHT_ASSIGN, ">>=", start);
}
return new BaseToken(ETokenType.RIGHT_OP, ">>", start);
return BaseToken.pool.get(ETokenType.RIGHT_OP, ">>", start);
} else if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.GE_OP, ">=", start);
return BaseToken.pool.get(ETokenType.GE_OP, ">=", start);
}
return new BaseToken(ETokenType.RIGHT_ANGLE, ">", start);
return BaseToken.pool.get(ETokenType.RIGHT_ANGLE, ">", start);

case "+":
this.advance();
if (this.getCurChar() === "+") {
this.advance();
return new BaseToken(ETokenType.INC_OP, "++", start);
return BaseToken.pool.get(ETokenType.INC_OP, "++", start);
} else if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.ADD_ASSIGN, "+=", start);
return BaseToken.pool.get(ETokenType.ADD_ASSIGN, "+=", start);
}
return new BaseToken(ETokenType.PLUS, "+", start);
return BaseToken.pool.get(ETokenType.PLUS, "+", start);

case "-":
this.advance();
if (this.getCurChar() === "-") {
this.advance();
return new BaseToken(ETokenType.DEC_OP, "--", start);
return BaseToken.pool.get(ETokenType.DEC_OP, "--", start);
} else if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.SUB_ASSIGN, "-=", start);
return BaseToken.pool.get(ETokenType.SUB_ASSIGN, "-=", start);
}
return new BaseToken(ETokenType.DASH, "-", start);
return BaseToken.pool.get(ETokenType.DASH, "-", start);

case "=":
this.advance();
if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.EQ_OP, "==", start);
return BaseToken.pool.get(ETokenType.EQ_OP, "==", start);
}
return new BaseToken(ETokenType.EQUAL, "=", start);
return BaseToken.pool.get(ETokenType.EQUAL, "=", start);

case "!":
this.advance();
if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.NE_OP, "!=", start);
return BaseToken.pool.get(ETokenType.NE_OP, "!=", start);
}
return new BaseToken(ETokenType.BANG, "!", start);
return BaseToken.pool.get(ETokenType.BANG, "!", start);

case "&":
this.advance();
if (this.getCurChar() === "&") {
this.advance();
return new BaseToken(ETokenType.AND_OP, "&&", start);
return BaseToken.pool.get(ETokenType.AND_OP, "&&", start);
} else if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.ADD_ASSIGN, "&=", start);
return BaseToken.pool.get(ETokenType.ADD_ASSIGN, "&=", start);
}
return new BaseToken(ETokenType.AMPERSAND, "&", start);
return BaseToken.pool.get(ETokenType.AMPERSAND, "&", start);

case "|":
this.advance();
if (this.getCurChar() === "|") {
this.advance();
return new BaseToken(ETokenType.OR_OP, "||", start);
return BaseToken.pool.get(ETokenType.OR_OP, "||", start);
} else if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.OR_ASSIGN, "|=", start);
return BaseToken.pool.get(ETokenType.OR_ASSIGN, "|=", start);
}
return new BaseToken(ETokenType.VERTICAL_BAR, "|", start);
return BaseToken.pool.get(ETokenType.VERTICAL_BAR, "|", start);

case "^":
this.advance();
if (this.getCurChar() === "^") {
this.advance();
return new BaseToken(ETokenType.XOR_OP, "^^", start);
return BaseToken.pool.get(ETokenType.XOR_OP, "^^", start);
} else if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.XOR_ASSIGN, "^=", start);
return BaseToken.pool.get(ETokenType.XOR_ASSIGN, "^=", start);
}
return new BaseToken(ETokenType.CARET, "^", start);
return BaseToken.pool.get(ETokenType.CARET, "^", start);

case "*":
this.advance();
if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.MUL_ASSIGN, "*=", start);

return BaseToken.pool.get(ETokenType.MUL_ASSIGN, "*=", start);
}
return new BaseToken(ETokenType.STAR, "*", start);

return BaseToken.pool.get(ETokenType.STAR, "*", start);

case "/":
this.advance();
if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.DIV_ASSIGN, "/=", start);

return BaseToken.pool.get(ETokenType.DIV_ASSIGN, "/=", start);
}
return new BaseToken(ETokenType.SLASH, "/", start);

return BaseToken.pool.get(ETokenType.SLASH, "/", start);

case "%":
this.advance();
if (this.getCurChar() === "=") {
this.advance();
return new BaseToken(ETokenType.MOD_ASSIGN, "%=", start);

return BaseToken.pool.get(ETokenType.MOD_ASSIGN, "%=", start);
}
return new BaseToken(ETokenType.PERCENT, "%", start);

return BaseToken.pool.get(ETokenType.PERCENT, "%", start);

case "(":
this.advance();
return new BaseToken(ETokenType.LEFT_PAREN, "(", start);

return BaseToken.pool.get(ETokenType.LEFT_PAREN, "(", start);
case ")":
this.advance();
return new BaseToken(ETokenType.RIGHT_PAREN, ")", start);

return BaseToken.pool.get(ETokenType.RIGHT_PAREN, ")", start);
case "{":
this.advance();
return new BaseToken(ETokenType.LEFT_BRACE, "{", start);

return BaseToken.pool.get(ETokenType.LEFT_BRACE, "{", start);
case "}":
this.advance();
return new BaseToken(ETokenType.RIGHT_BRACE, "}", start);

return BaseToken.pool.get(ETokenType.RIGHT_BRACE, "}", start);
case "[":
this.advance();
return new BaseToken(ETokenType.LEFT_BRACKET, "[", start);

return BaseToken.pool.get(ETokenType.LEFT_BRACKET, "[", start);
case "]":
this.advance();
return new BaseToken(ETokenType.RIGHT_BRACKET, "]", start);

return BaseToken.pool.get(ETokenType.RIGHT_BRACKET, "]", start);
case ".":
this.advance();
if (LexerUtils.isNum(this.getCurChar())) {
return this.scanNumAfterDot();
}
return new BaseToken(ETokenType.DOT, ".", start);

return BaseToken.pool.get(ETokenType.DOT, ".", start);
case ",":
this.advance();
return new BaseToken(ETokenType.COMMA, ",", start);

return BaseToken.pool.get(ETokenType.COMMA, ",", start);
case ":":
this.advance();
return new BaseToken(ETokenType.COLON, ":", start);

return BaseToken.pool.get(ETokenType.COLON, ":", start);
case ";":
this.advance();
return new BaseToken(ETokenType.SEMICOLON, ";", start);

return BaseToken.pool.get(ETokenType.SEMICOLON, ";", start);
case "~":
this.advance();
return new BaseToken(ETokenType.TILDE, "~", start);

return BaseToken.pool.get(ETokenType.TILDE, "~", start);
case "?":
this.advance();
return new BaseToken(ETokenType.QUESTION, "?", start);

return BaseToken.pool.get(ETokenType.QUESTION, "?", start);
case '"':
this.advance();
return this.scanStringConst();
Expand All @@ -220,7 +238,8 @@ export class Lexer extends BaseScanner {
}
this.advance();
const range = ShaderLab.createRange(start, this.getPosition());
return new BaseToken(ETokenType.STRING_CONST, buffer.join(""), range);

return BaseToken.pool.get(ETokenType.STRING_CONST, buffer.join(""), range);
}

private scanNumAfterDot() {
Expand All @@ -229,7 +248,8 @@ export class Lexer extends BaseScanner {
buffer.push(this.getCurChar());
this.advance();
}
return new BaseToken(ETokenType.FLOAT_CONSTANT, buffer.join(""), this.getPosition(1));

return BaseToken.pool.get(ETokenType.FLOAT_CONSTANT, buffer.join(""), this.getPosition(1));
}

private getPosition(offset /** offset from starting point */ = 0) {
Expand Down Expand Up @@ -259,9 +279,10 @@ export class Lexer extends BaseScanner {
const word = buffer.join("");
const kt = KeywordTable.get(word);
if (kt) {
return new BaseToken(kt, word, start);
return BaseToken.pool.get(kt, word, start);
}
return new BaseToken(ETokenType.ID, word, start);

return BaseToken.pool.get(ETokenType.ID, word, start);
}

private scanNum() {
Expand All @@ -278,14 +299,17 @@ export class Lexer extends BaseScanner {
this.advance();
}
this.scanFloatSuffix(buffer);
return new BaseToken(ETokenType.FLOAT_CONSTANT, buffer.join(""), this.getPosition(buffer.length));

return BaseToken.pool.get(ETokenType.FLOAT_CONSTANT, buffer.join(""), this.getPosition(buffer.length));
} else {
if (this.getCurChar() === "e" || this.getCurChar() === "E") {
this.scanFloatSuffix(buffer);
return new BaseToken(ETokenType.FLOAT_CONSTANT, buffer.join(""), this.getPosition(buffer.length));

return BaseToken.pool.get(ETokenType.FLOAT_CONSTANT, buffer.join(""), this.getPosition(buffer.length));
} else {
this.scanIntegerSuffix(buffer);
return new BaseToken(ETokenType.INT_CONSTANT, buffer.join(""), this.getPosition(buffer.length));

return BaseToken.pool.get(ETokenType.INT_CONSTANT, buffer.join(""), this.getPosition(buffer.length));
}
}
}
Expand Down
Loading

0 comments on commit 1d13f40

Please sign in to comment.