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

WIP: Improvements for Relocatable Compilations Part 3 #2920

Closed
wants to merge 14 commits into from

Conversation

dsouzai
Copy link
Contributor

@dsouzai dsouzai commented Sep 18, 2018

Depends on #2919 and eclipse-omr/omr#2979

Irwin D'Souza added 2 commits September 17, 2018 18:10
When the JIT heuristically decides to disable the SelectiveNoOptServer,
it only does so on the JIT Options object. This commit also sets the
option on the AOT Options object.

Signed-off-by: Irwin D'Souza <[email protected]>
If the user specifies higher method counts, don't delay relocation and
make the scount the same as the count.

Signed-off-by: Irwin D'Souza <[email protected]>
@dsouzai dsouzai changed the title Improvements for Relocatable Compilations Part 3 WIP: Improvements for Relocatable Compilations Part 3 Sep 18, 2018
@dsouzai dsouzai force-pushed the AOTImprovementsPart3 branch 2 times, most recently from 9e93981 to d38e950 Compare September 18, 2018 21:13
Irwin D'Souza added 12 commits September 18, 2018 17:35
In AOT, the compiler can only konw about classes that can be remembered
(ie, stored in the Shared Class Cache (SCC)). However, for functional
correctness, before loading an AOT compiled body, the code needs to be
validated in order to guarantee that the assumptions made about the java
environment during the compile run are still valid in the load run.

Currently, there are two types of validations; Arbitrary Class
validations and Class From Constant Pool (CP) validations. The former
can only apply to classes the compiler gets by name, when the name is a
string literal (eg a class loaded by the Bootstrap Class Loader). The
latter is used for classes the compiler gets from the CP of another
class.

Many queries in the compiler that get Class by Name have a
default parameter that can be set to vett the callsite for AOT. However,
these validations are not sufficient to provide confidence to vett a
site. The reason is because the query that gets the class by name is
used when the class name string is parsed from the signature of method;
in this case, the class that should be returned can be different
depending on who the "beholder" is. Additionally, if the compiler finds
a class that's not by name and not through a CP (eg string peepholes),
then under the current AOT infrastructure, the class can't be used.

This commit adds the infrastructure to enable validations of classes
regardless of how the compiler acquired them. The infrastructure is
general, in that it can be extended to enable validations of any kind of
symbol that the compiler acquires that may be different or non-existent
in the load run.

The fundamental idea is to store validation records every time a front
end query is made. The record holds information about the symbol
acquired, how it was acquired, and what information is required to
acquire it in the load run. Each symbol is given a unique ID. In the
load run, the AOT validation infrastructure goes through the validation
records and asks the same questions the compiler asked during the AOT
compilation, and if the answers vary in any way, the AOT load fails.
Otherwise, we are guaranteed that the code is entirely valid.

For example, if the method being compiled is A.foo(), then before the
compilation begins, the compiler creates:

1. Root Class Record for A
2. Method From Class Record for foo()

This will result in A getting ID 1, and foo() getting ID 2. As the
compilation continues, if the compiler gets class B in two different
ways, namely once by name and once via CP, then two other records get
created:

3. Class by Name for B
4. Class from CP for B

and B gets assigned ID 3.

In the AOT load run, all the AOT infrastructure can see are IDs.
Therefore, it has to reconstruct the symbols from these IDs. First it
goes through the Root Class Record, and determines what Class A is in
the new environment. Then it goes through the Method From Class Record
and searches for method foo(). Then it goes through the Class by Name
record and determines what B is. Then it goes through the Class from CP
record, and validates that the class it gets from the CP is the same as
the class it got by name, since in the compile run, those two queries
yielded the same answer. If after going through all the records
everything stays consistent, then the load passes.

An added subtlety that was not described in the example above is that
whenever a class record is created, a class chain record is also
created. The reason for this is because AOT can only work with classes
that can be remembered. Additionally, the class chains ensure that the
shape of the class is the same from run to run.

Another subtlety comes from array classes. Because array classes don't
have a unique ROMClass, the validation manager remembers the leaf
component class, and stores as many Array Class from Component Class
records as there are dimensions of the array class being validated.

Signed-off-by: Irwin D'Souza
The Symbol Validation Manager is used to remember all the different ways
the compiler acquired a symbol. However, there are regions where this
information isn't necessary for the load run. For example, when asking
for something from the Persistent CH Table, all that matters is the
input to the query and the output; however, the query involves going
through multiple classes before finally returning the answer. If the
compiler were to store valiations for everything that occurs during this
query, it would require consistency between the compile and load run for
more than what is only required for the compilation.

Therefore, this commit adds the means to denote regions that are not
strictly necessary to validate for the load run.

Signed-off-by: Irwin D'Souza <[email protected]>
Signed-off-by: Irwin D'Souza
Previously, because almost everything was "unresolved" under AOT, all
calls would use the unresolved dispatch. However, with the new
validations, very few unresolved pointers are only unresolved because of
AOT. Therefore, generating an unresolved dispatch is incorrect.

The solution to this problem is to assume, during an AOT compile, that
all methods are interpreted. Thus, if a method is resolved, the compiler
will generate a resolved interpreter dispatch snippet, which can patch
the caller if/when the method is compiled.

Signed-off-by: Irwin D'Souza <[email protected]>
Previously, Object Allocation Inlining under AOT maintained certain
assumtpions about the trees that was only true if the class was
unresolved. This commit fixes those assumptions.

Signed-off-by: Irwin D'Souza
Signed-off-by: Irwin D'Souza <[email protected]>
Signed-off-by: Irwin D'Souza <[email protected]>
Add query for when the compiler asks about whether a method is
interpreted for heuristic reasons, and not for functional correctness
reasons.

Signed-off-by: Irwin D'Souzai <[email protected]>
@dsouzai dsouzai force-pushed the AOTImprovementsPart3 branch from d38e950 to 2ba01e8 Compare September 18, 2018 21:38
@dsouzai dsouzai closed this Sep 19, 2018
@dsouzai dsouzai deleted the AOTImprovementsPart3 branch September 21, 2018 19:16
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.

1 participant