'. 'LooseSameTypeVisitor.checkSameBounds()' will
currently return 'false' when the upper bound of 'P' is recursively
checked (see [1]) which will then make
'LooseSameTypeVisitor.sameTypeVars()' return 'false' (see [2]).
I think 'LooseSameTypeVisitor.checkSameBounds()' should return 'true'
within recursive calls because only the root of recursion is able to
effectively check the bounds.
Fixing this little bug, as below, gives roughly the same results as
previously when using a cache (from 2x to 5x faster than initially).
Of course, it will still require some optimization to be sub-second
(as you said), but this simple correction could do half of the job.
What do you think?
Thanks,
Bernard
[1] http://hg.openjdk.java.net/jdk10/master/file/6d0e943bcd24/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java#l1452
[2] http://hg.openjdk.java.net/jdk10/master/file/6d0e943bcd24/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java#l1432
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
@@ -1449,7 +1449,7 @@
cache.remove(p);
}
} else {
- return false;
+ return true;
}
}
};
> Cheers
> Maurizio
From maurizio.cimadamore at oracle.com Fri Nov 3 01:58:37 2017
From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore)
Date: Fri, 3 Nov 2017 01:58:37 +0000
Subject: Linear implementation of Tarjan's algorithm
In-Reply-To:

is the same as P' <: Comparable

, because of
the f-bound. That's why the cache is there - it's not an optimization,
is something that prevents javac from doing the same check over and over
again.
When such a loop occurs, the right thing to do is to say 'false', as it
is not possible to prove that the bounds are indeed the same. Note that
the fact that the two variables are clones is largely irrelevant here -
we clone new tvars every time we check a new instance of the same
generic method call/diamond constructor - so in a way these are all
different variables which just happen to have the same name/same set of
initial (declared) bounds.
Moreover, the 'loose' type equality test is an artifact of the past - it
was introduced because the strict behavior (which was the default in 6)
was, well, sometimes too strict - essentially, if bounds of a type
variable are replaced for other type variables (e.g. replace U in the
bound of 'Z extends List__'), javac creates a different type-variable
with the replaced bound. If you performed the same replacement twice on
the original variable, the resulting replaced vars would not be deemed
'equals' by javac, which is why this looser behavior was added. Some
more comments are added here:
http://hg.openjdk.java.net/jdk7/jdk7/langtools/file/tip/src/share/classes/com/sun/tools/javac/code/Types.java#l632
These changes have been added as a consequence of the fixes for:
https://bugs.openjdk.java.net/browse/JDK-6729401
Now, all this is relatively ancient history, which predates the Java 8
changes - in fact, this 'legacy' loose behavior, is very problematic -
it's completely outside the spec, and, in the general case with fbounds,
it cannot even be proven to always complete (which is why the cache is
there). During 8, I sidestepped this issue by adding the 'strict' type
equality check, which should become the 'standard' - but, as I there was
only so much code I could rewrite in one shot (:-)), I added the new
routine beside the old one, instead of having the new routine completely
replacing the old one (and deal with the compatibility fallout).
I think the time is come that we do a bit of spring cleaning in the
area, and get rid of the legacy (and unsound) loose check, and see where
we're at.
That said, speaking of inference performances, if we ever move the
entire code base to use the strict equality check, your proposed
optimization would not even apply - in a way your optimization is
exploiting the fact that that particular check is using the loose check
instead of the strict one - with the strict one, two different type var
instances (no matter if they are clones, and even have same bounds) will
still be deemed different.
I still stand by my earlier analysis that the particular issue
highlighted in 8152289 is not something that needs to be addressed by
looking at the profiler. While you can make the bottleneck smaller and
smaller, you still have an underlying behavior that doesn't scale with
the number of nested calls - with increasing values of N, you do 10,
100, 1000, 10000, 1000 ....00000 checks - so no matter how fast the
rewritten logic is, you can always add a bunch new nested call to bring
the compilation time more or less in time to what it was before the fix.
The real fix is to find a way so that the incorporation machinery
doesn't have to actually perform a number of steps that is exponential
in the number of the type variables involved, and to detect patterns
that can be exploited in order to reduce the complexity of the
incorporation step.
Thanks
Maurizio
From bsrbnd at gmail.com Fri Nov 3 13:17:37 2017
From: bsrbnd at gmail.com (B. Blaser)
Date: Fri, 3 Nov 2017 14:17:37 +0100
Subject: Linear implementation of Tarjan's algorithm
In-Reply-To:
References: __

__ is the same as P' <: Comparable__

, because of the > f-bound. That's why the cache is there - it's not an optimization, is > something that prevents javac from doing the same check over and over again. > > When such a loop occurs, the right thing to do is to say 'false', as it is > not possible to prove that the bounds are indeed the same. If we want to prove that "P <: Comparable

__" is the same type as "P'
<: Comparable__

", we have to do something like the following lines
of Prolog:
% same(P1, P2) :- samesym(P1, P2), samebounds(comparable(P1), comparable(P2)).
% samebounds(comparable(P1), comparable(P2)) :- samesym(P1, P2),
cache(comparable(P1), comparable(P2)).
To prove 'same(P1, P2)', we have to know about 'samesym(P1, P2)' and
'cache(comparable(P1), comparable(P2))'.
Looking at the implementation, we find that 'samesym(P1, P2)' is given
by 'P1.tsym == P2.tsym' and 'cache(comparable(P1), comparable(P2))'
currently returns 'false'.
Now, we can look at the truth table for 'samesym()' and 'cache()':
% samesym(P1, P2) :- true.
% cache(comparable(P1), comparable(P2)) :- true.
%
% ?- same(P1, P2).
% true.
% samesym(P1, P2) :- true.
% cache(comparable(P1), comparable(P2)) :- false.
%
% ?- same(P1, P2).
% false.
% samesym(P1, P2) :- false.
% cache(comparable(P1), comparable(P2)) :- true.
%
% ?- same(P1, P2).
% false.
% samesym(P1, P2) :- false.
% cache(comparable(P1), comparable(P2)) :- false.
%
% ?- same(P1, P2).
% false.
We see that the only way to prove that 'same(P1, P2) = true' is to
postulate that 'cache(...) = true' which is what I suggested.
If we make the opposite hypothesis that 'cache(...) = false', which is
currently done, we will never be able to prove that 'same(P, P) =
true'... but the strict comparison would do that successfully!
What do you think (for the rest, I agree with you)?
Bernard
> Note that the
> fact that the two variables are clones is largely irrelevant here - we clone
> new tvars every time we check a new instance of the same generic method
> call/diamond constructor - so in a way these are all different variables
> which just happen to have the same name/same set of initial (declared)
> bounds.
>
> Moreover, the 'loose' type equality test is an artifact of the past - it was
> introduced because the strict behavior (which was the default in 6) was,
> well, sometimes too strict - essentially, if bounds of a type variable are
> replaced for other type variables (e.g. replace U in the bound of 'Z extends
> List__'), javac creates a different type-variable with the replaced bound.
> If you performed the same replacement twice on the original variable, the
> resulting replaced vars would not be deemed 'equals' by javac, which is why
> this looser behavior was added. Some more comments are added here:
>
> http://hg.openjdk.java.net/jdk7/jdk7/langtools/file/tip/src/share/classes/com/sun/tools/javac/code/Types.java#l632
>
> These changes have been added as a consequence of the fixes for:
>
> https://bugs.openjdk.java.net/browse/JDK-6729401
>
> Now, all this is relatively ancient history, which predates the Java 8
> changes - in fact, this 'legacy' loose behavior, is very problematic - it's
> completely outside the spec, and, in the general case with fbounds, it
> cannot even be proven to always complete (which is why the cache is there).
> During 8, I sidestepped this issue by adding the 'strict' type equality
> check, which should become the 'standard' - but, as I there was only so much
> code I could rewrite in one shot (:-)), I added the new routine beside the
> old one, instead of having the new routine completely replacing the old one
> (and deal with the compatibility fallout).
>
> I think the time is come that we do a bit of spring cleaning in the area,
> and get rid of the legacy (and unsound) loose check, and see where we're at.
>
> That said, speaking of inference performances, if we ever move the entire
> code base to use the strict equality check, your proposed optimization would
> not even apply - in a way your optimization is exploiting the fact that that
> particular check is using the loose check instead of the strict one - with
> the strict one, two different type var instances (no matter if they are
> clones, and even have same bounds) will still be deemed different.
>
> I still stand by my earlier analysis that the particular issue highlighted
> in 8152289 is not something that needs to be addressed by looking at the
> profiler. While you can make the bottleneck smaller and smaller, you still
> have an underlying behavior that doesn't scale with the number of nested
> calls - with increasing values of N, you do 10, 100, 1000, 10000, 1000
> ....00000 checks - so no matter how fast the rewritten logic is, you can
> always add a bunch new nested call to bring the compilation time more or
> less in time to what it was before the fix.
>
> The real fix is to find a way so that the incorporation machinery doesn't
> have to actually perform a number of steps that is exponential in the number
> of the type variables involved, and to detect patterns that can be exploited
> in order to reduce the complexity of the incorporation step.
>
> Thanks
> Maurizio
From maurizio.cimadamore at oracle.com Fri Nov 3 13:57:40 2017
From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore)
Date: Fri, 3 Nov 2017 13:57:40 +0000
Subject: Linear implementation of Tarjan's algorithm
In-Reply-To:
References: __

__ is the same as P' <: Comparable__

, because of the >> f-bound. That's why the cache is there - it's not an optimization, is >> something that prevents javac from doing the same check over and over again. >> >> When such a loop occurs, the right thing to do is to say 'false', as it is >> not possible to prove that the bounds are indeed the same. > If we want to prove that "P <: Comparable

__" is the same type as "P'
> <: Comparable__

", we have to do something like the following lines
> of Prolog:
>
> % same(P1, P2) :- samesym(P1, P2), samebounds(comparable(P1), comparable(P2)).
> % samebounds(comparable(P1), comparable(P2)) :- samesym(P1, P2),
> cache(comparable(P1), comparable(P2)).
>
> To prove 'same(P1, P2)', we have to know about 'samesym(P1, P2)' and
> 'cache(comparable(P1), comparable(P2))'.
> Looking at the implementation, we find that 'samesym(P1, P2)' is given
> by 'P1.tsym == P2.tsym' and 'cache(comparable(P1), comparable(P2))'
> currently returns 'false'.
>
> Now, we can look at the truth table for 'samesym()' and 'cache()':
>
> % samesym(P1, P2) :- true.
> % cache(comparable(P1), comparable(P2)) :- true.
> %
> % ?- same(P1, P2).
> % true.
>
> % samesym(P1, P2) :- true.
> % cache(comparable(P1), comparable(P2)) :- false.
> %
> % ?- same(P1, P2).
> % false.
>
> % samesym(P1, P2) :- false.
> % cache(comparable(P1), comparable(P2)) :- true.
> %
> % ?- same(P1, P2).
> % false.
>
> % samesym(P1, P2) :- false.
> % cache(comparable(P1), comparable(P2)) :- false.
> %
> % ?- same(P1, P2).
> % false.
>
> We see that the only way to prove that 'same(P1, P2) = true' is to
> postulate that 'cache(...) = true' which is what I suggested.
>
> If we make the opposite hypothesis that 'cache(...) = false', which is
> currently done, we will never be able to prove that 'same(P, P) =
> true'... but the strict comparison would do that successfully!
>
> What do you think (for the rest, I agree with you)?
>
> Bernard
>
>
>> Note that the
>> fact that the two variables are clones is largely irrelevant here - we clone
>> new tvars every time we check a new instance of the same generic method
>> call/diamond constructor - so in a way these are all different variables
>> which just happen to have the same name/same set of initial (declared)
>> bounds.
>>
>> Moreover, the 'loose' type equality test is an artifact of the past - it was
>> introduced because the strict behavior (which was the default in 6) was,
>> well, sometimes too strict - essentially, if bounds of a type variable are
>> replaced for other type variables (e.g. replace U in the bound of 'Z extends
>> List__'), javac creates a different type-variable with the replaced bound.
>> If you performed the same replacement twice on the original variable, the
>> resulting replaced vars would not be deemed 'equals' by javac, which is why
>> this looser behavior was added. Some more comments are added here:
>>
>> http://hg.openjdk.java.net/jdk7/jdk7/langtools/file/tip/src/share/classes/com/sun/tools/javac/code/Types.java#l632
>>
>> These changes have been added as a consequence of the fixes for:
>>
>> https://bugs.openjdk.java.net/browse/JDK-6729401
>>
>> Now, all this is relatively ancient history, which predates the Java 8
>> changes - in fact, this 'legacy' loose behavior, is very problematic - it's
>> completely outside the spec, and, in the general case with fbounds, it
>> cannot even be proven to always complete (which is why the cache is there).
>> During 8, I sidestepped this issue by adding the 'strict' type equality
>> check, which should become the 'standard' - but, as I there was only so much
>> code I could rewrite in one shot (:-)), I added the new routine beside the
>> old one, instead of having the new routine completely replacing the old one
>> (and deal with the compatibility fallout).
>>
>> I think the time is come that we do a bit of spring cleaning in the area,
>> and get rid of the legacy (and unsound) loose check, and see where we're at.
>>
>> That said, speaking of inference performances, if we ever move the entire
>> code base to use the strict equality check, your proposed optimization would
>> not even apply - in a way your optimization is exploiting the fact that that
>> particular check is using the loose check instead of the strict one - with
>> the strict one, two different type var instances (no matter if they are
>> clones, and even have same bounds) will still be deemed different.
>>
>> I still stand by my earlier analysis that the particular issue highlighted
>> in 8152289 is not something that needs to be addressed by looking at the
>> profiler. While you can make the bottleneck smaller and smaller, you still
>> have an underlying behavior that doesn't scale with the number of nested
>> calls - with increasing values of N, you do 10, 100, 1000, 10000, 1000
>> ....00000 checks - so no matter how fast the rewritten logic is, you can
>> always add a bunch new nested call to bring the compilation time more or
>> less in time to what it was before the fix.
>>
>> The real fix is to find a way so that the incorporation machinery doesn't
>> have to actually perform a number of steps that is exponential in the number
>> of the type variables involved, and to detect patterns that can be exploited
>> in order to reduce the complexity of the incorporation step.
>>
>> Thanks
>> Maurizio
From maurizio.cimadamore at oracle.com Fri Nov 3 14:00:35 2017
From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore)
Date: Fri, 3 Nov 2017 14:00:35 +0000
Subject: Linear implementation of Tarjan's algorithm
In-Reply-To: <878a12b6-2f93-f10c-2fba-f7894aee9e14@oracle.com>
References:
<451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr>
<8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com>
__

__ is the same as P' <: Comparable__

, because of the >>> f-bound. That's why the cache is there - it's not an optimization, is >>> something that prevents javac from doing the same check over and >>> over again. >>> >>> When such a loop occurs, the right thing to do is to say 'false', as >>> it is >>> not possible to prove that the bounds are indeed the same. >> If we want to prove that "P <: Comparable

__" is the same type as "P'
>> <: Comparable__

", we have to do something like the following lines
>> of Prolog:
>>
>> % same(P1, P2) :- samesym(P1, P2), samebounds(comparable(P1),
>> comparable(P2)).
>> % samebounds(comparable(P1), comparable(P2)) :- samesym(P1, P2),
>> cache(comparable(P1), comparable(P2)).
>>
>> To prove 'same(P1, P2)', we have to know about 'samesym(P1, P2)' and
>> 'cache(comparable(P1), comparable(P2))'.
>> Looking at the implementation, we find that 'samesym(P1, P2)' is given
>> by 'P1.tsym == P2.tsym' and 'cache(comparable(P1), comparable(P2))'
>> currently returns 'false'.
>>
>> Now, we can look at the truth table for 'samesym()' and 'cache()':
>>
>> % samesym(P1, P2) :- true.
>> % cache(comparable(P1), comparable(P2)) :- true.
>> %
>> % ?- same(P1, P2).
>> % true.
>>
>> % samesym(P1, P2) :- true.
>> % cache(comparable(P1), comparable(P2)) :- false.
>> %
>> % ?- same(P1, P2).
>> % false.
>>
>> % samesym(P1, P2) :- false.
>> % cache(comparable(P1), comparable(P2)) :- true.
>> %
>> % ?- same(P1, P2).
>> % false.
>>
>> % samesym(P1, P2) :- false.
>> % cache(comparable(P1), comparable(P2)) :- false.
>> %
>> % ?- same(P1, P2).
>> % false.
>>
>> We see that the only way to prove that 'same(P1, P2) = true' is to
>> postulate that 'cache(...) = true' which is what I suggested.
>>
>> If we make the opposite hypothesis that 'cache(...) = false', which is
>> currently done, we will never be able to prove that 'same(P, P) =
>> true'... but the strict comparison would do that successfully!
>>
>> What do you think (for the rest, I agree with you)?
>>
>> Bernard
>>
>>
>>> Note that the
>>> fact that the two variables are clones is largely irrelevant here -
>>> we clone
>>> new tvars every time we check a new instance of the same generic method
>>> call/diamond constructor - so in a way these are all different
>>> variables
>>> which just happen to have the same name/same set of initial (declared)
>>> bounds.
>>>
>>> Moreover, the 'loose' type equality test is an artifact of the past
>>> - it was
>>> introduced because the strict behavior (which was the default in 6)
>>> was,
>>> well, sometimes too strict - essentially, if bounds of a type
>>> variable are
>>> replaced for other type variables (e.g. replace U in the bound of 'Z
>>> extends
>>> List__'), javac creates a different type-variable with the replaced
>>> bound.
>>> If you performed the same replacement twice on the original
>>> variable, the
>>> resulting replaced vars would not be deemed 'equals' by javac, which
>>> is why
>>> this looser behavior was added. Some more comments are added here:
>>>
>>> http://hg.openjdk.java.net/jdk7/jdk7/langtools/file/tip/src/share/classes/com/sun/tools/javac/code/Types.java#l632
>>>
>>>
>>> These changes have been added as a consequence of the fixes for:
>>>
>>> https://bugs.openjdk.java.net/browse/JDK-6729401
>>>
>>> Now, all this is relatively ancient history, which predates the Java 8
>>> changes - in fact, this 'legacy' loose behavior, is very problematic
>>> - it's
>>> completely outside the spec, and, in the general case with fbounds, it
>>> cannot even be proven to always complete (which is why the cache is
>>> there).
>>> During 8, I sidestepped this issue by adding the 'strict' type equality
>>> check, which should become the 'standard' - but, as I there was only
>>> so much
>>> code I could rewrite in one shot (:-)), I added the new routine
>>> beside the
>>> old one, instead of having the new routine completely replacing the
>>> old one
>>> (and deal with the compatibility fallout).
>>>
>>> I think the time is come that we do a bit of spring cleaning in the
>>> area,
>>> and get rid of the legacy (and unsound) loose check, and see where
>>> we're at.
>>>
>>> That said, speaking of inference performances, if we ever move the
>>> entire
>>> code base to use the strict equality check, your proposed
>>> optimization would
>>> not even apply - in a way your optimization is exploiting the fact
>>> that that
>>> particular check is using the loose check instead of the strict one
>>> - with
>>> the strict one, two different type var instances (no matter if they are
>>> clones, and even have same bounds) will still be deemed different.
>>>
>>> I still stand by my earlier analysis that the particular issue
>>> highlighted
>>> in 8152289 is not something that needs to be addressed by looking at
>>> the
>>> profiler. While you can make the bottleneck smaller and smaller, you
>>> still
>>> have an underlying behavior that doesn't scale with the number of
>>> nested
>>> calls - with increasing values of N, you do 10, 100, 1000, 10000, 1000
>>> ....00000 checks - so no matter how fast the rewritten logic is, you
>>> can
>>> always add a bunch new nested call to bring the compilation time
>>> more or
>>> less in time to what it was before the fix.
>>>
>>> The real fix is to find a way so that the incorporation machinery
>>> doesn't
>>> have to actually perform a number of steps that is exponential in
>>> the number
>>> of the type variables involved, and to detect patterns that can be
>>> exploited
>>> in order to reduce the complexity of the incorporation step.
>>>
>>> Thanks
>>> Maurizio
>
From karen.kinnear at oracle.com Fri Nov 3 18:14:53 2017
From: karen.kinnear at oracle.com (Karen Kinnear)
Date: Fri, 3 Nov 2017 14:14:53 -0400
Subject: [10] RFR 8186046 Minimal ConstantDynamic support
In-Reply-To:
References:
Message-ID: <8D52F736-587E-48A2-BD9C-003A690187DD@oracle.com>
Thank you so much for doing this jointly.
Couple of questions/comments:
1. thank you for making UseBootstrapCallInfo diagnostic
2. org/objectweb/asmClassReader.java
why hardcoded 17 instead of ClassWriter.CONDY?
3. java/lang/invoke/package-info.java 128-134
Error handling could be clearer.
My understanding is that if a LinkageError or subclass is thrown, this will be rethrown
for all subsequent attempts. Other errors, e.g. VMError may retry resolution
Also: after line 165: rules do not enable the JVM to share call sites.
Is it worth noting anywhere that the Constant_Dynamic resolution is shared?
4. SD::find_java_mirror_for_type
lines 2679+
ConDy should not be supporting CONSTANT_Class(?;? + FD)
IIRC that is temporary for MVT but not part of ConDy?s spec, nor part of what
should be checked in for 18.3
also line 2731 - remove comment about ?Foo;?
5. constantTag.hpp
ofBasicType: case T_OBJECT return constantTag(JVM_CONSTANT_String) ?
why not JVM_CONSTANT_CLASS?
6. SD::find_java_mirror_for_type
You have resolve_or_null/fail doing CHECK_(empty) which should
check for a NULL constant_type_klass. This is followed by an explicit if
(constant_type_klass == NULL) ? is that needed?
7. reflection.cpp
get_mirror_from_signature
Looks like potential for side effects. Odd to set mirror_oop inside if (log_is_enabled)
Is the intent to assert that k->java_mirror() == mirror_oop?
Or is the issue that we have a make drop here and the potential for a safe point?
If so, make a handle and extract it on return?
? Or better yet - don?t make any changes to reflection.cpp - not necessary
8. BootstrapMethodInvoker
Could you possibly add a comment that the default today is vmIsPushing and IsPullModeBSM is false?
Or find a slightly different naming to make that clearer?
9. test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/InstructionHelper.java
How would I write an ldc CONSTANT_Dynamic which referred to a bootstrap method that
was not ACC_STATIC?
Or was not ACC_PUBLIC?
Or was
Or did I read the invoke dynamic method incorrectly?
thanks,
Karen
> On Oct 26, 2017, at 1:03 PM, Paul Sandoz __

__ is the same as P' <: Comparable__

, because of the >>>> f-bound. That's why the cache is there - it's not an optimization, is >>>> something that prevents javac from doing the same check over and over >>>> again. >>>> >>>> When such a loop occurs, the right thing to do is to say 'false', as it >>>> is >>>> not possible to prove that the bounds are indeed the same. >>> >>> If we want to prove that "P <: Comparable

__" is the same type as "P'
>>> <: Comparable__

", we have to do something like the following lines
>>> of Prolog:
>>>
>>> % same(P1, P2) :- samesym(P1, P2), samebounds(comparable(P1),
>>> comparable(P2)).
>>> % samebounds(comparable(P1), comparable(P2)) :- samesym(P1, P2),
>>> cache(comparable(P1), comparable(P2)).
>>>
>>> To prove 'same(P1, P2)', we have to know about 'samesym(P1, P2)' and
>>> 'cache(comparable(P1), comparable(P2))'.
>>> Looking at the implementation, we find that 'samesym(P1, P2)' is given
>>> by 'P1.tsym == P2.tsym' and 'cache(comparable(P1), comparable(P2))'
>>> currently returns 'false'.
>>>
>>> Now, we can look at the truth table for 'samesym()' and 'cache()':
>>>
>>> % samesym(P1, P2) :- true.
>>> % cache(comparable(P1), comparable(P2)) :- true.
>>> %
>>> % ?- same(P1, P2).
>>> % true.
>>>
>>> % samesym(P1, P2) :- true.
>>> % cache(comparable(P1), comparable(P2)) :- false.
>>> %
>>> % ?- same(P1, P2).
>>> % false.
>>>
>>> % samesym(P1, P2) :- false.
>>> % cache(comparable(P1), comparable(P2)) :- true.
>>> %
>>> % ?- same(P1, P2).
>>> % false.
>>>
>>> % samesym(P1, P2) :- false.
>>> % cache(comparable(P1), comparable(P2)) :- false.
>>> %
>>> % ?- same(P1, P2).
>>> % false.
>>>
>>> We see that the only way to prove that 'same(P1, P2) = true' is to
>>> postulate that 'cache(...) = true' which is what I suggested.
>>>
>>> If we make the opposite hypothesis that 'cache(...) = false', which is
>>> currently done, we will never be able to prove that 'same(P, P) =
>>> true'... but the strict comparison would do that successfully!
>>>
>>> What do you think (for the rest, I agree with you)?
>>>
>>> Bernard
>>>
>>>
>>>> Note that the
>>>> fact that the two variables are clones is largely irrelevant here - we
>>>> clone
>>>> new tvars every time we check a new instance of the same generic method
>>>> call/diamond constructor - so in a way these are all different variables
>>>> which just happen to have the same name/same set of initial (declared)
>>>> bounds.
>>>>
>>>> Moreover, the 'loose' type equality test is an artifact of the past - it
>>>> was
>>>> introduced because the strict behavior (which was the default in 6) was,
>>>> well, sometimes too strict - essentially, if bounds of a type variable
>>>> are
>>>> replaced for other type variables (e.g. replace U in the bound of 'Z
>>>> extends
>>>> List__'), javac creates a different type-variable with the replaced
>>>> bound.
>>>> If you performed the same replacement twice on the original variable,
>>>> the
>>>> resulting replaced vars would not be deemed 'equals' by javac, which is
>>>> why
>>>> this looser behavior was added. Some more comments are added here:
>>>>
>>>>
>>>> http://hg.openjdk.java.net/jdk7/jdk7/langtools/file/tip/src/share/classes/com/sun/tools/javac/code/Types.java#l632
>>>>
>>>> These changes have been added as a consequence of the fixes for:
>>>>
>>>> https://bugs.openjdk.java.net/browse/JDK-6729401
>>>>
>>>> Now, all this is relatively ancient history, which predates the Java 8
>>>> changes - in fact, this 'legacy' loose behavior, is very problematic -
>>>> it's
>>>> completely outside the spec, and, in the general case with fbounds, it
>>>> cannot even be proven to always complete (which is why the cache is
>>>> there).
>>>> During 8, I sidestepped this issue by adding the 'strict' type equality
>>>> check, which should become the 'standard' - but, as I there was only so
>>>> much
>>>> code I could rewrite in one shot (:-)), I added the new routine beside
>>>> the
>>>> old one, instead of having the new routine completely replacing the old
>>>> one
>>>> (and deal with the compatibility fallout).
>>>>
>>>> I think the time is come that we do a bit of spring cleaning in the
>>>> area,
>>>> and get rid of the legacy (and unsound) loose check, and see where we're
>>>> at.
>>>>
>>>> That said, speaking of inference performances, if we ever move the
>>>> entire
>>>> code base to use the strict equality check, your proposed optimization
>>>> would
>>>> not even apply - in a way your optimization is exploiting the fact that
>>>> that
>>>> particular check is using the loose check instead of the strict one -
>>>> with
>>>> the strict one, two different type var instances (no matter if they are
>>>> clones, and even have same bounds) will still be deemed different.
>>>>
>>>> I still stand by my earlier analysis that the particular issue
>>>> highlighted
>>>> in 8152289 is not something that needs to be addressed by looking at the
>>>> profiler. While you can make the bottleneck smaller and smaller, you
>>>> still
>>>> have an underlying behavior that doesn't scale with the number of nested
>>>> calls - with increasing values of N, you do 10, 100, 1000, 10000, 1000
>>>> ....00000 checks - so no matter how fast the rewritten logic is, you can
>>>> always add a bunch new nested call to bring the compilation time more or
>>>> less in time to what it was before the fix.
>>>>
>>>> The real fix is to find a way so that the incorporation machinery
>>>> doesn't
>>>> have to actually perform a number of steps that is exponential in the
>>>> number
>>>> of the type variables involved, and to detect patterns that can be
>>>> exploited
>>>> in order to reduce the complexity of the incorporation step.
>>>>
>>>> Thanks
>>>> Maurizio
>>
>>
>
From paul.sandoz at oracle.com Fri Nov 3 21:28:54 2017
From: paul.sandoz at oracle.com (Paul Sandoz)
Date: Fri, 3 Nov 2017 14:28:54 -0700
Subject: [10] RFR 8186046 Minimal ConstantDynamic support
In-Reply-To: <8D52F736-587E-48A2-BD9C-003A690187DD@oracle.com>
References:
<8D52F736-587E-48A2-BD9C-003A690187DD@oracle.com>
Message-ID: <3205F35B-0262-4BEE-B645-6D02021757D2@oracle.com>
> On 3 Nov 2017, at 11:14, Karen Kinnear __