public final class LoopConditionProfile extends ConditionProfile
LoopConditionProfiles are designed to profile the outcome of loop conditions. Loop profiles can be used to profile unpredictable loops as well as predictable loops.
Arbitrary loop usage example:
class LoopNode extends Node { final LoopConditionProfile loopProfile = LoopConditionProfile.createCountingProfile(); void execute() { // loop count cannot be predicted while (loopProfile.profile(Math.random() >= 0.9)) { // work } } }
Counted loop usage example:
class CountedLoopNode extends Node { final LoopConditionProfile loopProfile = LoopConditionProfile.createCountingProfile(); void execute(int length) { // loop count can be predicted loopProfile.profileCounted(length); for (int i = 0; loopProfile.inject(i < length); i++) { // work } } }
The advantage of using LoopConditionProfile.profileCounted(long)
to using LoopConditionProfile.profile(boolean)
is that
it incurs less overhead in the interpreter. Using LoopConditionProfile.inject(boolean)
is
a no-op in the interpreter while LoopConditionProfile.profile(boolean)
needs to use a counter for each
iteration.
ConditionProfiles are useful to profile the outcome of conditions. A regular condition profile
keeps track of a binary state, for each branch whether a branch was hit or not and communicates
this to the compiler. If frequency information for each branch should be collected use
CountingConditionProfile
instead.
Usage example:
class AbsoluteNode extends Node { final ConditionProfile greaterZeroProfile = ConditionProfile.create(); void execute(int value) { if (greaterZeroProfile.profile(value >= 0)) { return value; } else { return -value; } } }
A profile is a Truffle utility class that uses the Truffle compiler
directives
to guard for and/or forward runtime information to the compiler. Whenever Truffle DSL
can be used inlined profiles
subclasses should be used instead of regular
profile
subclasses.
Usage: Profiles should be stored in final
or compilation final
fields of node classes to ensure that they can get optimized properly.
Profiles must not be shared between ASTs. Using the same profile multiple times in a single
node
or in multiple nodes
which link
to the
same root
is allowed. Never store profiles inside runtime values that
leave the scope of the originating AST. This limitation exists because the used mechanism to
invalidate compiled code performs local invalidations only. For global speculations use
assumptions
instead.
Compilation: Some profiles like branch
profiles do not induce
additional overhead in compiled code. Others like value
profiles might
require a runtime check to verify their assumptions which are forwarded to the compiler. Even if
profiles do not induce direct overhead in compiled code it still might get invalidated as a
result of using profiles. Invalidating profiles will result in the invalidation of compiled code.
It is therefore essential to place these profiles in way that is neither too aggressive nor too
conservative.
Footprint: Whether profiling information can be forwarded to the compiler depends on the
capabilities of the runtime system
. If the runtime returns
true
in TruffleRuntime.isProfilingEnabled()
then runtime information will
get collected. This comes at at the cost of additional overhead and footprint in interpreted
mode. Thats why the factory methods of profiles can return implementations where profiling is
disabled. Using disabled profiles makes sense for runtimes that are unable to use the collected
profiling information. Even runtime implementations that are able to use this information might
decide to turn off profiling for benchmarking purposes.
Profile subclasses:
BranchProfile
to profile on unlikely branches like errors.ConditionProfile
to profile on conditionals or boolean values.LoopConditionProfile
to profile on conditionals of loops with special support for
counted loops.ValueProfile
to profile on properties like type and identity of values.ByteValueProfile
to profile on byte
values.IntValueProfile
to profile on int
values.LongValueProfile
to profile on long
values.FloatValueProfile
to profile on float
values.DoubleValueProfile
to profile on double
values.PrimitiveValueProfile
to profile on objects by identity and on primitives by value.
LoopConditionProfile.create()
,
LoopConditionProfile
Modifier and Type | Method and Description |
---|---|
static LoopConditionProfile |
create()
Returns a
LoopConditionProfile that speculates on loop conditions to be never
true . |
void |
disable()
Disables this profile by setting it to its generic state.
|
static LoopConditionProfile |
getUncached()
Returns the uncached version of the profile.
|
boolean |
inject(boolean condition)
Provides an alternative way to profile counted loops with less interpreter footprint.
|
boolean |
profile(boolean condition) |
void |
profileCounted(long length)
Provides an alternative way to profile counted loops with less interpreter footprint.
|
void |
reset()
Resets this profile to its uninitialized state.
|
String |
toString() |
inline
clone
public boolean profile(boolean condition)
profile
in class ConditionProfile
public void profileCounted(long length)
LoopConditionProfile
for an usage example.LoopConditionProfile.inject(boolean)
public boolean inject(boolean condition)
LoopConditionProfile
for an usage example.LoopConditionProfile.inject(boolean)
public void disable()
deoptimize
on any
invocation of a profile method.
This method must not be called on compiled code paths. Note that disabling the profile will not invalidate existing compiled code that uses this profile.
disable
in class ConditionProfile
public void reset()
This method must not be called on compiled code paths. Note that disabling the profile will not invalidate existing compiled code that uses this profile.
reset
in class ConditionProfile
public String toString()
toString
in class ConditionProfile
public static LoopConditionProfile create()
LoopConditionProfile
that speculates on loop conditions to be never
true
. It also captures loop probabilities for the compiler. Loop condition
profiles are intended to be used for loop conditions.public static LoopConditionProfile getUncached()