Skip to content

Commit 3260e10

Browse files
committed
perf: optimize searching breakpoints in bitmapset.c
1 parent f5d39a8 commit 3260e10

File tree

1 file changed

+38
-39
lines changed

1 file changed

+38
-39
lines changed

src/variables.ts

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -381,13 +381,20 @@ export class StepContext {
381381
* Name of function which frame we are currently observing.
382382
*/
383383
currentFunctionName?: string;
384+
385+
/*
386+
* Whether is it safe for not get elements of Bitmapset.
387+
* Main concern are breakpoints in bitmapset.c
388+
*/
389+
isSafeToObserveBitmapset?: boolean;
384390

385391
reset() {
386392
this.isSafeToAllocateMemory = undefined;
387393
this.rtable.rtable = undefined;
388394
this.rtable.waiter = undefined;
389395
this.rtable.exists = false;
390396
this.currentFunctionName = undefined;
397+
this.isSafeToObserveBitmapset = undefined;
391398
}
392399
}
393400

@@ -4020,17 +4027,6 @@ export class ArraySpecialMember extends RealVariable {
40204027
* Bitmapset variable
40214028
*/
40224029
class BitmapSetSpecialMember extends NodeVariable {
4023-
/*
4024-
* List of functions that we are using for bitmapset evaluation.
4025-
* We need to ensure, that no breakpoints set on them, otherwise
4026-
* we encounter infinite loop
4027-
*/
4028-
private static evaluationUsedFunctions = [
4029-
'bms_next_member',
4030-
'bms_first_member',
4031-
'bms_is_valid_set',
4032-
];
4033-
40344030
constructor(args: RealVariableArgs) {
40354031
super('Bitmapset', args);
40364032
}
@@ -4088,38 +4084,41 @@ class BitmapSetSpecialMember extends NodeVariable {
40884084

40894085
return true;
40904086
}
4091-
4092-
safeToObserve() {
4087+
4088+
isBreakpointDangerous(bp: vscode.Breakpoint) {
40934089
/*
4094-
* Fastest way I found is just to iterate all breakpoints and check
4095-
* - no bp in bitmapset.c source code for line breakpoints
4096-
* - no bp for bms_next_member function for function breakpoints
4097-
*
4098-
* I have found only these 2 subclasses of breakpoints.
4099-
* Seems that it is enough.
4090+
* Fastest way is just to iterate all breakpoints and check if
4091+
* breakpoint is dangerous, meaning that if we will stop, then can
4092+
* end up in infinite loop or precondition (state) can be violated.
4093+
*
4094+
* For now such breakpoints includes all functions inside bitmapset.c -
4095+
* main file with all Bitmapset manipulation logic.
41004096
*/
4101-
for (const bp of vscode.debug.breakpoints) {
4102-
if (!bp.enabled) {
4103-
continue;
4104-
}
4097+
if (!bp.enabled) {
4098+
return false;
4099+
}
41054100

4106-
if (bp instanceof vscode.SourceBreakpoint) {
4107-
if (bp.location.uri.path.endsWith('bitmapset.c')) {
4108-
logger.info('found breakpoint at bitmapset.c - set elements not shown');
4109-
return false;
4110-
}
4111-
} else if (bp instanceof vscode.FunctionBreakpoint) {
4112-
/*
4113-
* Need to check functions that are called to get set elements
4114-
*/
4115-
if (BitmapSetSpecialMember.evaluationUsedFunctions.indexOf(bp.functionName) !== -1) {
4116-
logger.info('found breakpoint at %s - bms elements not shown',
4117-
bp.functionName);
4118-
return false;
4119-
}
4120-
}
4101+
if (bp instanceof vscode.SourceBreakpoint) {
4102+
return bp.location.uri.path.endsWith('bitmapset.c');
41214103
}
4122-
return true;
4104+
4105+
if (bp instanceof vscode.FunctionBreakpoint) {
4106+
/*
4107+
* All Bitmapset functions have 'bms_' prefix.
4108+
* I can track which ones are dangerous, but if someday someone
4109+
* will create another dangerous function then logic will be broken,
4110+
* so add such simple check, so code will live longer.
4111+
*/
4112+
return bp.functionName.startsWith('bms_');
4113+
}
4114+
4115+
/* Other breakpoints must be safe */
4116+
return false;
4117+
}
4118+
4119+
safeToObserve() {
4120+
return this.context.step.isSafeToObserveBitmapset
4121+
??= !!vscode.debug.breakpoints.find(this.isBreakpointDangerous);
41234122
}
41244123

41254124
async getSetElements(members: Variable[]): Promise<number[] | undefined> {

0 commit comments

Comments
 (0)