Re: Free-before-allocate in Java

2018-11-15 Thread Gil Tene
This one is "tricky" in a fun way.

>From a language semantics point of view, the compiler is probably allowed 
to perform the optimization suggested (removing the null assignment to a 
non-volatile field, knowing that it will soon be overwritten), which does 
raise an interesting point about the language semantics and OOM conditions.

However, from a practical implementation point of view, it is "hard" [my 
shorthand for "it may be impossible, but I can't prove it, or don't want to 
bother trying"] to perform this optimization in a way that would eliminate 
the null assignment from a GC perspective, because there is an object 
allocation between the two assignments. The difficulty comes from the fact 
that even in optimized code (in current JVM implementations), all 
allocation sites retain the ability to take a safepoint. Here is the logic:

- The allocation attempt *may* need to wait for a GC to complete (e.g. if a 
GC is needed in order to produce the empty memory that the allocation will 
use).

- A GC can't be guaranteed to complete (in all current practical JVM 
implementations) without transitioning all threads (at the very least 
temporarily and individually, if not simultaneously and globally) to a 
safepoint.

- Since the thread must be able to "come to a safepoint" at the allocation 
site (which sits between the first and second assignments), and since 
safepoints can end up being used for things other than GC (such as 
deoptimization, breakpoints, etc.), the JVM state at the safepoint must be 
completely reconstructible.

- If a safepoint is taken at the allocation site. the state of the JVM at 
that safepoint would include the memory outcome of the first assignment and 
*not* include the outcome second assignment.

- Therefore, *IF* the safepoint is taken, the null assignment must occur 
before it is taken.

Technically, this can either defeat the optimization altogether (which is 
what it will do for most JITs). However, it is possible to keep the 
optimization in the fast path (allocation doesn't take a safepoint) if a 
JIT was able to push code into the path between the poll to determine if a 
safepoint is needed and actually reaching the safepoint. If the JIT has 
that ability, the null assignment code could be moved around such that it 
occurs only if a safepoint is actually taken, and is skipped if a safepoint 
is not taken.

Either way (regardless of whether the optimization is defeated, or the null 
is moved to happen only in the safepoint-taking path), the null assignment 
would occur before GC is ever forced at the allocation site. This will 
explain why you won't see an OOM on that allocation on current JVMs, even 
with JIT-optimized code, even if the heap is only large enough to 
accommodate one copy of the byte[].

On Tuesday, November 13, 2018 at 9:28:18 AM UTC-8, Shevek wrote:
>
> Given the following code: 
>
> byte[] data = ...; 
>
> { 
> data = null; 
> data = new byte[N]; 
> } 
>
> Is the compiler allowed to discard the assignment of null, because it's 
> "dead" in language terms? My argument is that it isn't dead because it 
> allows the garbage collector to respond to pressure within the 'new' and 
> reuse the space, but in language terms, this presumably isn't defined, 
> and it would seem to be legal for the first assignment to be removed. 
>
> Thank you. 
>
> S. 
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Free-before-allocate in Java

2018-11-15 Thread Science Student
Technically the 3rd line is not even needed for compiler to optimize away
the 1st line. Thoughts?

On Thu, Nov 15, 2018, 9:53 AM Margaret Figura  Hi,
>
> I see why the compiler should be able to remove the first assignment, but
> (just for fun) I'm having trouble getting it to actually do it. With my
> -Xmx setting, I should see an OutOfMemoryError as soon as the first
> assignment is optimized away because the heap is large enough for only 1
> copy of the new byte[] in the second assignment.
>
> So, I'm wondering if this can actually happen. And if not, is it because
> the JIT just doesn't detect this possible optimization, or because it's
> smart enough to realize the trick I'm trying to play on it.
>
> -Meg
>
> On Tuesday, November 13, 2018 at 1:05:43 PM UTC-5, Jean-Philippe BEMPEL
> wrote:
>>
>> Hi,
>>
>> JIT Compiler is allowed to discard the null assisgnment because there are
>> 2 consecutives writes into the same location, so only the last one can be
>> kept without changing the meaning of the program.
>> From the GC point of view as soon as the reference is no longer pointing
>> to the allocate object, it is considered as dead, and may be reclaimed in
>> the next cycle.
>> But depending on if data is a field or local variable will determine if
>> GC can reclaim it sooner.
>> In the case of a local variable as soon as the variable is no more read,
>> a GC can already collect the byte[] before assigning local variable to null
>> (with the help of liveness analysis).
>> For the field case, the byte[] will reclaimable once the assignment is
>> done, so maybe after the allocation of the second byte[]
>>
>> Regards
>>
>> On Tue, Nov 13, 2018 at 6:28 PM Shevek  wrote:
>>
>>> Given the following code:
>>>
>>> byte[] data = ...;
>>>
>>> {
>>> data = null;
>>> data = new byte[N];
>>> }
>>>
>>> Is the compiler allowed to discard the assignment of null, because it's
>>> "dead" in language terms? My argument is that it isn't dead because it
>>> allows the garbage collector to respond to pressure within the 'new' and
>>> reuse the space, but in language terms, this presumably isn't defined,
>>> and it would seem to be legal for the first assignment to be removed.
>>>
>>> Thank you.
>>>
>>> S.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "mechanical-sympathy" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to mechanical-sympathy+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "mechanical-sympathy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mechanical-sympathy+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Free-before-allocate in Java

2018-11-15 Thread Margaret Figura
Hi,

I see why the compiler should be able to remove the first assignment, but 
(just for fun) I'm having trouble getting it to actually do it. With my 
-Xmx setting, I should see an OutOfMemoryError as soon as the first 
assignment is optimized away because the heap is large enough for only 1 
copy of the new byte[] in the second assignment.

So, I'm wondering if this can actually happen. And if not, is it because 
the JIT just doesn't detect this possible optimization, or because it's 
smart enough to realize the trick I'm trying to play on it.

-Meg

On Tuesday, November 13, 2018 at 1:05:43 PM UTC-5, Jean-Philippe BEMPEL 
wrote:
>
> Hi,
>
> JIT Compiler is allowed to discard the null assisgnment because there are 
> 2 consecutives writes into the same location, so only the last one can be 
> kept without changing the meaning of the program.
> From the GC point of view as soon as the reference is no longer pointing 
> to the allocate object, it is considered as dead, and may be reclaimed in 
> the next cycle.
> But depending on if data is a field or local variable will determine if GC 
> can reclaim it sooner.
> In the case of a local variable as soon as the variable is no more read, a 
> GC can already collect the byte[] before assigning local variable to null 
> (with the help of liveness analysis). 
> For the field case, the byte[] will reclaimable once the assignment is 
> done, so maybe after the allocation of the second byte[]
>
> Regards
>
> On Tue, Nov 13, 2018 at 6:28 PM Shevek > 
> wrote:
>
>> Given the following code:
>>
>> byte[] data = ...;
>>
>> {
>> data = null;
>> data = new byte[N];
>> }
>>
>> Is the compiler allowed to discard the assignment of null, because it's 
>> "dead" in language terms? My argument is that it isn't dead because it 
>> allows the garbage collector to respond to pressure within the 'new' and 
>> reuse the space, but in language terms, this presumably isn't defined, 
>> and it would seem to be legal for the first assignment to be removed.
>>
>> Thank you.
>>
>> S.
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "mechanical-sympathy" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to mechanical-sympathy+unsubscr...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Free-before-allocate in Java

2018-11-13 Thread Jean-Philippe BEMPEL
Hi,

JIT Compiler is allowed to discard the null assisgnment because there are 2
consecutives writes into the same location, so only the last one can be
kept without changing the meaning of the program.
>From the GC point of view as soon as the reference is no longer pointing to
the allocate object, it is considered as dead, and may be reclaimed in the
next cycle.
But depending on if data is a field or local variable will determine if GC
can reclaim it sooner.
In the case of a local variable as soon as the variable is no more read, a
GC can already collect the byte[] before assigning local variable to null
(with the help of liveness analysis).
For the field case, the byte[] will reclaimable once the assignment is
done, so maybe after the allocation of the second byte[]

Regards

On Tue, Nov 13, 2018 at 6:28 PM Shevek  wrote:

> Given the following code:
>
> byte[] data = ...;
>
> {
> data = null;
> data = new byte[N];
> }
>
> Is the compiler allowed to discard the assignment of null, because it's
> "dead" in language terms? My argument is that it isn't dead because it
> allows the garbage collector to respond to pressure within the 'new' and
> reuse the space, but in language terms, this presumably isn't defined,
> and it would seem to be legal for the first assignment to be removed.
>
> Thank you.
>
> S.
>
> --
> You received this message because you are subscribed to the Google Groups
> "mechanical-sympathy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mechanical-sympathy+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Free-before-allocate in Java

2018-11-13 Thread Shevek

Given the following code:

byte[] data = ...;

{
   data = null;
   data = new byte[N];
}

Is the compiler allowed to discard the assignment of null, because it's 
"dead" in language terms? My argument is that it isn't dead because it 
allows the garbage collector to respond to pressure within the 'new' and 
reuse the space, but in language terms, this presumably isn't defined, 
and it would seem to be legal for the first assignment to be removed.


Thank you.

S.

--
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.