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

Instrumenter to observe behavior of nodes with UUID #7833

Merged
merged 35 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
99cb39e
Instrumenter to observe behavior of nodes with UUID
JaroslavTulach Sep 18, 2023
ea79b89
Instrumentor test
JaroslavTulach Sep 18, 2023
6f1a609
Return back original version of the comment
JaroslavTulach Sep 19, 2023
69ecf06
Remove unnecessary metadata from the test
JaroslavTulach Sep 19, 2023
9dae0cc
Merge remote-tracking branch 'origin/develop' into wip/jtulach/Instru…
JaroslavTulach Sep 20, 2023
aa8cff0
Compare also the final result
JaroslavTulach Sep 20, 2023
c9abb9c
Replay with (different) cache results
JaroslavTulach Sep 20, 2023
a4b02aa
Merge remote-tracking branch 'origin/develop' into wip/jtulach/Instru…
JaroslavTulach Oct 2, 2023
c41f70d
Adopt to hidden environment
JaroslavTulach Oct 2, 2023
1232a36
Adding documentation for the Instrumentor
JaroslavTulach Oct 2, 2023
1baefa5
Avoid onExceptionalCallback, propagate InteropException as PanicExcep…
JaroslavTulach Oct 3, 2023
9711534
Merging with Meta.Type.find
JaroslavTulach Oct 3, 2023
f5f2608
Treat Instrumentor as a managed resource
JaroslavTulach Oct 3, 2023
9c8b3e3
Merging with removal of onExceptionCallback
JaroslavTulach Oct 4, 2023
a68cd01
Deactivate self.impl
JaroslavTulach Oct 4, 2023
40fa087
Instrument tail recursive fibonacci
JaroslavTulach Oct 4, 2023
6fefaf3
Nicer display for builtin functions without source section
JaroslavTulach Oct 5, 2023
bfa4577
Testing behavior of on_call
JaroslavTulach Oct 5, 2023
f65c19a
Allow the on_call callback to change the result of function invocation
JaroslavTulach Oct 5, 2023
700c02c
on_enter replaces the whole regular execution and avoids on_call
JaroslavTulach Oct 5, 2023
6352d53
More robust, immutable implementation of Instrumentor
JaroslavTulach Oct 5, 2023
8f3bae5
Increase SerialVersionUID to prevent caches errors
JaroslavTulach Oct 5, 2023
7e7d61f
Increase SerialVersionUID to prevent caches errors
JaroslavTulach Oct 5, 2023
a5c7aa4
Note about Meta.instrument & Instrumentor API
JaroslavTulach Oct 5, 2023
7d12a37
Test to verify Instrumentor can be GCed
JaroslavTulach Oct 5, 2023
958ac95
Don't mangle return values when a binding handle has already been dis…
JaroslavTulach Oct 5, 2023
8b3d195
Using Windows version of the file
JaroslavTulach Oct 6, 2023
c303d1c
Removing obsolete code
JaroslavTulach Oct 6, 2023
e1b25bd
Resolving conflicts
JaroslavTulach Oct 7, 2023
b525fff
Merge branch 'develop' into wip/jtulach/Instrumenter_7683
mergify[bot] Oct 7, 2023
24b2976
Merge branch 'develop' into wip/jtulach/Instrumenter_7683
mergify[bot] Oct 9, 2023
22d3da1
Merge branch 'develop' into wip/jtulach/Instrumenter_7683
mergify[bot] Oct 9, 2023
0e49f2c
Trying to convince Git on Windows to not convert LF endings
JaroslavTulach Oct 9, 2023
a8da9f6
Convert CRLF to LF in the CLI tests
JaroslavTulach Oct 9, 2023
0f20687
Four more CRLF fixes
JaroslavTulach Oct 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,7 @@
- [Merge `Small_Integer` and `Big_Integer` types][7636]
- [Inline type ascriptions][7796]
- [Always persist `TRACE` level logs to a file][7825]
- [Meta.instrument & Instrumentor API][7833]
- [Downloadable VSCode extension][7861]
- [New `project/status` route for reporting LS state][7801]
- [Add Enso-specific assertions][7883])
Expand Down Expand Up @@ -1116,6 +1117,7 @@
[7796]: https://github.com/enso-org/enso/pull/7796
[7801]: https://github.com/enso-org/enso/pull/7801
[7825]: https://github.com/enso-org/enso/pull/7825
[7833]: https://github.com/enso-org/enso/pull/7833
[7861]: https://github.com/enso-org/enso/pull/7861
[7883]: https://github.com/enso-org/enso/pull/7883
[7840]: https://github.com/enso-org/enso/pull/7840
Expand Down
75 changes: 75 additions & 0 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import project.Data.Vector.Vector
import project.Error.Error as Base_Error
import project.Errors.Common.Not_Found
import project.Nothing.Nothing
import project.Function.Function
import project.Polyglot.Java
from project.Runtime.Managed_Resource import Managed_Resource
from project.Data.Boolean import Boolean, False, True

type Type
Expand Down Expand Up @@ -212,6 +214,13 @@ type Unresolved_Symbol
scope : Any
scope self = get_unresolved_symbol_scope self.value

## ADVANCED
GROUP Metadata

Starts building an instrumentation for a given node
instrument : Instrumentor
instrument self = Instrumentor.Value (instrumentor_builtin "newBuilder" [ self.value ])

type Error
## PRIVATE
ADVANCED
Expand Down Expand Up @@ -579,6 +588,72 @@ get_short_type_name typ = @Builtin_Method "Meta.get_short_type_name"
get_constructor_declaring_type : Any -> Any
get_constructor_declaring_type constructor = @Builtin_Method "Meta.get_constructor_declaring_type"

instrumentor_builtin op args = @Builtin_Method "Meta.instrumentor_builtin"

## PRIVATE
ADVANCED

Builder to create instrumentation for a function
type Instrumentor
## PRIVATE
Value impl

## PRIVATE
ADVANCED

Registers callback to be executed at the begining of node/expression
execution. The callback `fn` gets UUID of the node/expression that is
being executed and can return `Nothing` to continue regular execution
or anything else to skip the execution and just return given value.

Arguments:
- fn: The callback function accepting UUID.
on_enter self (fn : Text -> Any | Nothing) =
JaroslavTulach marked this conversation as resolved.
Show resolved Hide resolved
new = instrumentor_builtin "onEnter" [ self.impl, fn ]
Instrumentor.Value new

## PRIVATE
ADVANCED

Registers callback to be executed when a node/expression evaluation
is over. The callback `fn` gets UUID and the computed value. Usually
the value is _cached_ and returned from `on_enter` callback next time
the same expression is evaluated.

Arguments:
- fn: The callback function accepting UUID and computed value
on_return self (fn : Text -> Any -> Nothing) =
new = instrumentor_builtin "onReturn" [ self.impl, fn ]
Instrumentor.Value new

## PRIVATE
ADVANCED

Registers callback to be executed when a node/expression representing function is about to be called.
The callback `fn` shall accept three arguments. The UUID to identify the expression, the function to be
invoked and the arguments to pass to the function. The callback can return `Nothing`
(in such case the function gets executed with provided arguments) or some other value,
which is then returned instead of calling the function.

Arguments:
- fn: The callback function accepting UUID and function value
on_call self (fn : Text -> Function -> Vector Any -> Any | Nothing) =
new = instrumentor_builtin "onCall" [ self.impl, fn ]
Instrumentor.Value new

## PRIVATE
ADVANCED

Activates configured instrumentor. Returns managed resource to
deactivate the instrumentor later.

Arguments:
- value: The value of the atom in the meta representation.
activate self =
finalize_instrumentor impl = instrumentor_builtin "deactivate" [ impl ]
create action = (instrumentor_builtin action [ self.impl, finalize_instrumentor ]) : Managed_Resource
create "activate"

## PRIVATE
Returns type specified by fully qualified name.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.enso.polyglot.debugger;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.instrumentation.EventBinding;
import com.oracle.truffle.api.instrumentation.ExecutionEventNodeFactory;
import com.oracle.truffle.api.interop.TruffleObject;
import java.util.UUID;

public interface IdExecutionService {
String INSTRUMENT_ID = "id-value-extractor";

public interface Callbacks {
/**
* Finds out previously computed result for given id. If a result is returned, then the
* execution of given node is skipped and the value is returned back.
*
* @param nodeId identification of the node to be computed
* @return {@code null} should the execution of the node be performed; any other value to skip
* the execution and return the value as a result.
*/
Object findCachedResult(UUID nodeId);

/**
* Notifies when an execution of a node is over.
*
* @param nodeId identification of the node to be computed
* @param result the just computed result
* @param isPanic was the result a panic?
* @param nanoElapsedTime how long it took to compute the result?
*/
void updateCachedResult(UUID nodeId, Object result, boolean isPanic, long nanoElapsedTime);

/**
* Notification when a returned value is a function.
*
* @param nodeId identification of the node to be computed
* @param result info about function call
* @return {@code null} should the execution of the node be performed; any other value to skip
* the execution and return the value as a result.
*/
Object onFunctionReturn(UUID nodeId, TruffleObject result);
}

/**
* Attach a new event node factory to observe identified nodes within given function.
*
* @param module module that contains the code
* @param entryCallTarget the call target being observed.
* @param callbacks the interface to receive notifications
* @param timer the execution timer.
* @return a reference to the attached event node factory.
*/
EventBinding<ExecutionEventNodeFactory> bind(
TruffleObject module, CallTarget entryCallTarget, Callbacks callbacks, Object timer);
}
Loading