The speed gain is that method invocation may be not disturbed at all on HotSpot VMs, where
calls to this method may be fully optimized away as long as isRunning() is constant.
*/
if (isRunning()) {
SimpleArrayList callStack = transaction.getCallStack();
try {
if (args!=null) {
ObjectContainer caller = (ObjectContainer) callStack.peek();
if (caller!=null) {
/*
There is a design decision which heavily affects performance:
- Do we first check for the possibility of an OzoneProxy as parameter or
- Do we first check for the cross of the border of the different sets of database objects?
If we use true here, the first option is used.
If we use false here, the first option is used.
*/
if (false) {
/*
This spaghetti code is for speed.
- If we find an OzoneProxy, we have to look deeper and have to synchronize
- If we do not find an OzoneProxy, we do not have to look deeper and to synchronized
*/
checkForPossibleOzoneProxys:
for (;;) {
for (int i = args.length-1;i>=0;i--) {
if (args[i] instanceof OzoneProxy) {
break checkForPossibleOzoneProxys;
}
}
return;
}
}
boolean possibleProxyBorderCross = false;
synchronized (garbageCollectionLevelsLock) {
if (callee.getGarbageCollectionLevel()==doneReachableGarbageCollectionLevel) { // The callee belongs to the doneReachable set
if (caller.getGarbageCollectionLevel()!=doneReachableGarbageCollectionLevel) { // The caller does not belong to the doneReachable set
// The caller may transport object references to the doneReachable set where they are not checked. The referenced objects could falsely be identified as unreachable.
possibleProxyBorderCross = true;
}
}
}
if (possibleProxyBorderCross) {
for (int i = args.length-1;i>=0;i--) {
checkForProxyBorderCross(args[i]);
}
}
}
}
} finally {
callStack.push(callee);
}
}
}