Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Implement debug object for CLI #2772

Closed
wants to merge 7 commits into from

Conversation

HalidOdat
Copy link
Member

@HalidOdat HalidOdat commented Apr 1, 2023

Currently some debugging stuff in JavaScript land is difficult to impossible, like triggering a GC collect, this is not impossible to do in JavaScript the way I triggered it was by creating a huge amount of object for (let i = 0; i < 100000; ++i) { ({}) } but this is cumbersome and not guaranteed to trigger a gc.

This PR implements --debug-object flag that injects the $boa debug object in the context, the object is separated into modules currently gc, function, object.

We can now do $boa.gc.collect(), which force triggers a GC collect.

Or sometimes I wanted a trace (the current solution is great, you can trace stuff like >>> 1 + 1 but that is also it's limitation), it traces everything, I sometimes have a scenario and just want to trace a single function in that scenario, that's why I added the $boa.function.trace(func, this, ...args) It only traces the function.

>> $boa.function.trace((a, b) => a + b, undefined, 1, 2)

-------------------------Compiled Output: ''--------------------------
Location  Count   Opcode                     Operands

000000    0000    DefInitArg                 0000: 'a'
000005    0001    DefInitArg                 0001: 'b'
000010    0002    RestParameterPop           
000011    0003    GetName                    0000: 'a'
000016    0004    GetName                    0001: 'b'
000021    0005    Add                        
000022    0006    Return                     
000023    0007    PushUndefined              
000024    0008    Return                     

... (cut for brevity) ...

It also implements $boa.function.flowgraph(func, options):

$boa.function.flowgraph(func, 'graphviz')
$boa.function.flowgraph(func, { format: 'mermaid', direction: 'TopBottom' })

Printing the object pointer:

$boa.object.id({}) // '0x566464F33'

It currently implements some functionality which we can grow it with our debugging needs since we are not restricted by a spec we can add whatever we want :)

I was originally going to implement this in #2723 (but the PR is too big), for shapes having functions like:

$boa.shape.type({}) // Shared shape
$boa.shape.id({}) // 0x8578FG355 (objects, shape pointer)
$boa.shape.flowgraph({}) // printing the shape transition chain, like $boa.function.flowgraph

Shapes chains are very hard to debug once they are big... so having this type of debugging capability would make it much easier.

@HalidOdat HalidOdat added enhancement New feature or request cli Issues and PRs related to the Boa command line interface. labels Apr 1, 2023
@HalidOdat HalidOdat marked this pull request as ready for review April 1, 2023 15:34
@github-actions
Copy link

github-actions bot commented Apr 1, 2023

Test262 conformance changes

Test result main count PR count difference
Total 94,277 94,277 0
Passed 71,100 71,100 0
Ignored 17,324 17,324 0
Failed 5,853 5,853 0
Panics 0 0 0
Conformance 75.42% 75.42% 0.00%

@codecov
Copy link

codecov bot commented Apr 1, 2023

Codecov Report

Merging #2772 (3ad18d6) into main (08ed2a4) will decrease coverage by 0.27%.
The diff coverage is 0.92%.

@@            Coverage Diff             @@
##             main    #2772      +/-   ##
==========================================
- Coverage   50.98%   50.72%   -0.27%     
==========================================
  Files         409      414       +5     
  Lines       40759    40973     +214     
==========================================
+ Hits        20780    20782       +2     
- Misses      19979    20191     +212     
Impacted Files Coverage Δ
boa_cli/src/debug/function.rs 0.00% <0.00%> (ø)
boa_cli/src/debug/gc.rs 0.00% <0.00%> (ø)
boa_cli/src/debug/mod.rs 0.00% <0.00%> (ø)
boa_cli/src/debug/object.rs 0.00% <0.00%> (ø)
boa_cli/src/debug/optimizer.rs 0.00% <0.00%> (ø)
boa_cli/src/main.rs 0.80% <0.00%> (-0.01%) ⬇️
boa_engine/src/object/mod.rs 31.34% <0.00%> (-0.30%) ⬇️
boa_engine/src/vm/code_block.rs 47.09% <0.00%> (-0.22%) ⬇️
boa_engine/src/bytecompiler/mod.rs 63.10% <100.00%> (+0.04%) ⬆️
boa_engine/src/vm/mod.rs 57.86% <100.00%> (ø)

... and 1 file with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

Copy link
Member

@raskad raskad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition!

boa_cli/src/debug/gc.rs Outdated Show resolved Hide resolved
@HalidOdat
Copy link
Member Author

Now the .trace doesn't return the full compiled CodeBlock, only what it executed (called functions are not traced as suggested by @jedel1043 )

>> const add = (a, b) => a + b
>> $boa.function.trace(add, undefined, 1, 2)
5μs           DefInitArg                 0000: 'a'                  2
4μs           DefInitArg                 0001: 'b'                  <empty>
0μs           RestParameterPop                                      <empty>
3μs           GetName                    0000: 'a'                  1
1μs           GetName                    0001: 'b'                  2
2μs           Add                                                   3
1μs           Return                                                3
3
>>

If we want the full bytecode then, we can use the .bytecode function:

>> $boa.function.bytecode(add)
"
------------------------Compiled Output: 'add'------------------------
Location  Count   Opcode                     Operands

000000    0000    DefInitArg                 0000: 'a'
000005    0001    DefInitArg                 0001: 'b'
000010    0002    RestParameterPop           
000011    0003    GetName                    0000: 'a'
000016    0004    GetName                    0001: 'b'
000021    0005    Add                        
000022    0006    Return                     
000023    0007    PushUndefined              
000024    0008    Return                     

Literals:
    <empty>

Bindings:
    0000: a
    0001: b

Functions:
    <empty>
"
>>

@HalidOdat HalidOdat requested a review from jedel1043 April 2, 2023 01:26
@jasonwilliams
Copy link
Member

https://github.com/boa-dev/boa/blob/main/docs/debugging.md will need to be updated to cover this

Copy link
Member

@jedel1043 jedel1043 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provided @jasonwilliams's comment is addressed, this looks great to me!

@HalidOdat
Copy link
Member Author

HalidOdat commented Apr 3, 2023

Added documentation here (rendered)

I only included a small introduction in the debugging.md file and put the full doc for $boa in boa_object.md, since it's too big and will become bigger as we add other functionality, like shapes

Also added $boa.optimizer module for enabling/disabling of optimizations.

@jedel1043
Copy link
Member

bors r+

bors bot pushed a commit that referenced this pull request Apr 5, 2023
Currently some debugging stuff in JavaScript land is difficult to impossible, like triggering a GC collect, this is not impossible to do in JavaScript the way I triggered it was by creating a huge amount of object `for (let i = 0; i < 100000; ++i) { ({}) }` but this is cumbersome and not guaranteed to trigger a gc.

This PR implements `--debug-object` flag that injects the `$boa` debug object in the context, the object is separated into modules currently `gc`, `function`, `object`.

We can now do `$boa.gc.collect()`, which force triggers a GC collect.

Or sometimes I wanted a trace (the current solution is great, you can trace stuff like `>>> 1 + 1` but that is also it's limitation), it traces everything, I sometimes have a scenario and just want to trace a single function in that scenario, that's why I added the `$boa.function.trace(func, this, ...args)`  It only traces the function.

```js
>> $boa.function.trace((a, b) => a + b, undefined, 1, 2)

-------------------------Compiled Output: ''--------------------------
Location  Count   Opcode                     Operands

000000    0000    DefInitArg                 0000: 'a'
000005    0001    DefInitArg                 0001: 'b'
000010    0002    RestParameterPop           
000011    0003    GetName                    0000: 'a'
000016    0004    GetName                    0001: 'b'
000021    0005    Add                        
000022    0006    Return                     
000023    0007    PushUndefined              
000024    0008    Return                     

... (cut for brevity) ...
```

It also implements `$boa.function.flowgraph(func, options)`:
```js
$boa.function.flowgraph(func, 'graphviz')
$boa.function.flowgraph(func, { format: 'mermaid', direction: 'TopBottom' })
```

Printing the object pointer:
```js
$boa.object.id({}) // '0x566464F33'
```

It currently implements some functionality which we can grow it with our debugging needs since we are not restricted by a spec we can add whatever we want :)

I was originally going to implement this in #2723 (but the PR is too big), for shapes having functions like:
```js
$boa.shape.type({}) // Shared shape
$boa.shape.id({}) // 0x8578FG355 (objects, shape pointer)
$boa.shape.flowgraph({}) // printing the shape transition chain, like $boa.function.flowgraph
```
Shapes chains are very hard to debug once they are big... so having this type of debugging capability would make it much easier.
@bors
Copy link

bors bot commented Apr 5, 2023

Pull request successfully merged into main.

Build succeeded:

@bors bors bot changed the title Implement debug object for CLI [Merged by Bors] - Implement debug object for CLI Apr 5, 2023
@bors bors bot closed this Apr 5, 2023
@bors bors bot deleted the feature/debug-object branch April 5, 2023 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cli Issues and PRs related to the Boa command line interface. enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants