Skip to content

Code - #1

Open
jagotu wants to merge 89 commits into
reviewfrom
master
Open

Code#1
jagotu wants to merge 89 commits into
reviewfrom
master

Conversation

@jagotu

@jagotu jagotu commented Jan 25, 2021

Copy link
Copy Markdown
Owner

No description provided.

{
if(callNodes.containsKey(pc))
{
return callNodes.get(pc).execute(frame, primitives, refs);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

  • this must be a constant expression from the point of view of Truffle partial evaluation, i.e., simply computable from final and @CompilationFinal fields (note: all final fields are implicitly @CompilationFinal) and other partial evaluation constants (e.g., pc). For now you can use just sparse array indexed with pc, maybe it can be optimized to some compact representation later on. JDK's collections and most of the JDK classes in general are usually not suitable for partial evaluation (exception: strings, but not StringBuilder/Buffer).

  • all nodes must be stored in @Child or @Children annotated fields and unless you initialize them in the constructor, you must notify Truffle when you change them: mychildField = insert(new MyNode()). @Child(ren) annotation is implicitly @CompilationFinal.

  • you should use DirectCallNode constructed using Truffle.getRuntime().createDirectCallNode(). These nodes are known by Truffle and mark invocation of some other method, i.e., another RootNode. This allows Truffle to do method inlining.

  • the pattern to lazy initialization of a node is:

if (node == null) {
    CompilerDirectives.transferToInterepreterAndInvalidate(); // because we are about to change something that is compilation final
   this.node = insert(new MyNode())
}
// ... work with node

@jagotu jagotu changed the title Code as of 2012/01/25 Code Jan 25, 2021
jagotu added 24 commits January 26, 2021 00:01
from 4-5x times slower than dotnet to 1.75-2x
* foreign method calls with dependent assembly loading
* ManagedReferences
* Table loading now actually compliant with big tables
* long[] instead of byte[] accessed with unsafe
* temporarily deleted narrowing and widening to find raw performance issues
* pop opcode support
* function call fix
BACILHelpers + BACILConsoleType + BACILConsoleWriteMethod = stdout
Creating a bogus 0-element array is better optimized than possibly having null pointers
This allows caching of type for BOX (type lookup should never be on compiled path) and caching of the string value for LDSTR.
Comment thread thesis_text/thesis_text.md Outdated

While writing an interpreter for even a fairly complicated language is achievable for a single person interested in the topic, state-of-the-art optimizing compilers are usually created over several years by large teams of developers at the largest IT companies. Not only was kickstarting such a project unthinkable for an individual but even introducing changes to an already existing project is far from simple.

For example, Google's state-of-the-art JavaScript engine V8 currently has two different JIT compilers and its own internal bytecode. An experiment of adding a single new bytecode instruction to the project can mean several days of just orientating in the codebase.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

minor: místo currently bych používal všude "as of 2022" nebo podobné

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

a/nebo citace by byla pekna, oponenti maji radi citace

Comment thread thesis_text/thesis_text.md Outdated

For example, Google's state-of-the-art JavaScript engine V8 currently has two different JIT compilers and its own internal bytecode. An experiment of adding a single new bytecode instruction to the project can mean several days of just orientating in the codebase.

As cybersecurity becomes a more important topic, another factor to consider is that creating manual optimizations in JITs is very prone to bugs which can have very grave security implications. Speculated assumptions of JIT compilers introduced whole new bug families including "type confusion". Implementing a JIT that is not only performant but also secure is proving to be difficult even for state-of-the-art projects.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Na tohle by taky mohla byt nejaka hezka citace

Comment thread thesis_text/thesis_text.md Outdated
To implement a high-performance CLI runtime, we alleviate the
[Truffle language implementation framework](https://www.graalvm.org/graalvm-as-a-platform/language-implementation-framework/) (henceforth "Truffle") and the [GraalVM Compiler](https://www.graalvm.org/22.1/docs/introduction). These two components are tightly coupled together and we'll mostly be referring to them that way.

The Graal Compiler is a general high-performance just-in-time compiler for Java bytecode that is itself written in Java. It is state-of-the-art when it comes to optimization algorithms - according to official documentation, "the compiler in GraalVM Enterprise includes 62 optimization phases, of which 27 are patented".

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

reference

Comment thread thesis_text/thesis_text.md Outdated

Also, it is often useful to make sure some exceptional code paths are never included in the compilation - for example, if dividing by zero should result in an immediate crash of the application with a message being printed out, there is no use in spending time compiling and optimizing the error-message printing code, as it will at max be called once.

For that, Truffle uses guards - statements that when reached by the runtime result in de-optimization. De-optimization is a process of transferring evaluation from the compiled variant of the method back to the interpreter (at the precise point where it was interrupted) and throwing away the already compiled variant, as its assumptions no longer hold.

@steve-s steve-s May 12, 2022

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Timto jsou myslene guards v Graal IR? V Tuffle DSL, ktery jsi, myslim, nepouzil, je take koncept guardu a je to trochu neco jineho. Nevim, jestli to neni matouci.

Comment thread thesis_text/thesis_text.md Outdated

The Graal Compiler is a general high-performance just-in-time compiler for Java bytecode that is itself written in Java. It is state-of-the-art when it comes to optimization algorithms - according to official documentation, "the compiler in GraalVM Enterprise includes 62 optimization phases, of which 27 are patented".

Truffle on the other hand is a framework for implementing languages that will run on Graal. From the outside, it behaves like a compiler: its job is to take guest language code and convert it to the VM's language. Unlike a hand-crafted compiler, Truffle takes an interpreter of the guest language as its input and uses [Partial evaluation](#partial-evaluation) to do the compilation, performing a so-called "first Futamura projection".

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

will be compiled by Graal? or will run on GraalVM? Nekdy se rozlisuje Truffle framework nebo API (implementacni framework pro autory interpretru) a Truffle compiler == Graal compiler + compiler pluginy pro partial evaluation, ktere rozumneji tomu Truffle API


As long as the virtual call is effectively static at runtime, we only spend time compiling the actual target function (which can be specialized for the environment) and during invocation only pay the price of a simple equality check.

Once the comparison fails, this version of the compiled method is thrown away, and a generic one is created:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Mozna by se hodilo vysvetlit v cem je to lepsi nez:

if (obj.type == expectedType) return cache.call();
// else no deopt
return obj.Type.ResolveVirtualFunc(method).call();

takhle delal .NET profile-guided optimalizace posledne, kdyz jsem se na to dival, protoze jeste neumeli deopt, ale umeli tiered kompilaci

Comment thread thesis_text/thesis_text.md Outdated
return vars[a]
```

The original control flow of the method was reconstructed from flat bytecode just by unrolling the interpreter loop and merging the instances having the same bytecode offset.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Neni mi to ted jasne: "was reconstructed from flat bytecode just by unrolling the interpreter loop" -- jakoze jsme si to ted rucne udelali, abychom pak chapali, co dela Graal/Truffle compiler? Nebo was reconstructed by Truffle compiler? V tom pripade by tu mohl byt skec toho interpreter loopu?

Comment thread thesis_text/thesis_text.md Outdated

### Design goals

Before we started designing and implementing the parser, we considered what additional constraints have to be put on a parser in order for it to be partial-evaluation friendly. For partial-evaluation friendliness, the key metric is how trivial can every piece of code (that can be called a hot path) be partially evaluated to. While our goal was for the parser to never be called on a hot path, for some possible scenarios including reflection it would be necessary.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

"hot path" se bezne mezi Truffle vyvojari pouziva, presnejsi je asi neco jako "included in partial evaluation" nebo tak podobne. Mozna bys mohl nekde na zacatku definovat, co pro nas bude znamenat "hot path". IMO performance parseru je taky dulezita, coz je jedna z vyhod tve prace oproti te praci z Lince, a tak i v parseru budou nejake "hot paths" v urcitem slova smyslu

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Premyslim, jestli to nejak nedostat do problem statementu, protoze v jistem smyslu to byl tvuj goal udelat tohle lip nez to mel ten clovek z Lince. Objektivne vzato, pokud by bylo cilem jen udelat rychly interpreter, pak zkraceni cesty k tomuto cili pres zjenoduseni parsovani by mohlo byt validni. Dalsi hezka vec je, ze mas i language launcher podle Truffle "best practices", treba by se to taky dalo prodat i s tim

jagotu added 22 commits June 24, 2022 13:19
…ust to get 7 more successful tests

ValueTypes are unrolled (flattened) to their respective LocationsHolder. On evaluation stack they exist as plain LocationHolders. Most changes are caused by the fact that LocationDescriptor has  to remember offsets to both the primitives and refs arrays to fully mark a beginning of ValueType. A GetHashCode internalcall had to be implemented for them.
Required to generate the instanceFieldsDescriptor
Apart from abstract and conclusion the thesis should be content-complete!
Finally added a link to the thesis
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants