could someone point me in direction which might lead me to get why JIT deoptimizes my loop? (OSR). It looks like it gets compiled once by C1 and then its deoptimized multiple times (I can see tens or maybe hundred logs which starts with <deoptimized...>)
This is the class which contains that important loop:
@SynchronizationRequired
public class Worker implements Runnable
{
private static final byte NOT_RUNNING = 0, RUNNING = 1, SHUTDOWN = 2, FORCE_SHUTDOWN = 3;
private static final AtomicIntegerFieldUpdater<Worker> isRunningFieldUpdater =
AtomicIntegerFieldUpdater.newUpdater(Worker.class, "isRunning");
private volatile int isRunning = NOT_RUNNING;
private final Queue<FunkovConnection> tasks = new SpscUnboundedArrayQueue<>(512);
/**
* Executing tasks from queue until closed.
*/
@Override
public void run()
{
if (isRunning())
{
return;
}
while (notClosed())
{
FunkovConnection connection = tasks.poll();
if (null != connection)
{
connection.run();
}
}
if (forceShutdown())
{
setNonRunning();
return;
}
FunkovConnection connection;
while ((connection = tasks.poll()) != null)
{
connection.run();
}
setNonRunning();
}
public void submit(FunkovConnection connection)
{
tasks.add(connection);
}
/**
* Shutdowns worker after it finish processing all pending tasks on its queue
*/
public void shutdown()
{
isRunningFieldUpdater.compareAndSet(this, RUNNING, SHUTDOWN);
}
/**
* Shutdowns worker after it finish currently processing task. Pending tasks on queue are not handled
*/
public void shutdownForce()
{
isRunningFieldUpdater.compareAndSet(this, RUNNING, FORCE_SHUTDOWN);
}
private void setNonRunning()
{
isRunningFieldUpdater.set(this, NOT_RUNNING);
}
private boolean forceShutdown()
{
return isRunningFieldUpdater.get(this) == FORCE_SHUTDOWN;
}
private boolean isRunning()
{
return isRunningFieldUpdater.getAndSet(this, RUNNING) == RUNNING;
}
public boolean notClosed()
{
return isRunningFieldUpdater.get(this) == RUNNING;
}
}
JIT logs:
1. <task_queued compile_id='535' compile_kind='osr' method='Worker run ()V' bytes='81' count='1' backedge_count='60416' iicount='1' osr_bci='8' level='3' stamp='0,145' comment='tiered' hot_count='60416'/>
2. <nmethod compile_id='535' compile_kind='osr' compiler='c1' level='3' entry='0x00007fabf5514ee0' size='5592' address='0x00007fabf5514c10' relocation_offset='344' insts_offset='720' stub_offset='4432' scopes_data_offset='4704' scopes_pcs_offset='5040' dependencies_offset='5552' nul_chk_table_offset='5560' oops_offset='4624' metadata_offset='4640' method='Worker run ()V' bytes='81' count='1' backedge_count='65742' iicount='1' stamp='0,146'/>
3. <deoptimized thread='132773' reason='constraint' pc='0x00007fabf5515c24' compile_id='535' compile_kind='osr' compiler='c1' level='3'>
<jvms bci='37' method='Worker run ()V' bytes='81' count='1' backedge_count='68801' iicount='1'/>
</deoptimized>
4. <deoptimized thread='132773' reason='constraint' pc='0x00007fabf5515c24' compile_id='535' compile_kind='osr' compiler='c1' level='3'>
<jvms bci='37' method='Worker run ()V' bytes='81' count='1' backedge_count='76993' iicount='1'/>
</deoptimized>
5.<deoptimized thread='132773' reason='constraint' pc='0x00007fabf5515c24' compile_id='535' compile_kind='osr' compiler='c1' level='3'>
<jvms bci='37' method='Worker run ()V' bytes='81' count='1' backedge_count='85185' iicount='1'/>
</deoptimized>
6. <deoptimized thread='132773' reason='constraint' pc='0x00007fabf5515c24' compile_id='535' compile_kind='osr' compiler='c1' level='3'>
<jvms bci='37' method='Worker run ()V' bytes='81' count='1' backedge_count='93377' iicount='1'/>
</deoptimized>
Two questions here:
- What could be the reason for deoptimization? "constraint" seems not that meaningful to me
- Why there is so many logs about deoptimization, not just one? It look likes it's compiled once but decompiled multipile times


