2

I was debugging java.util.concurrent.locks.AbstractQueuedSynchronizer#acquireQueued method. And I found that the interrupted and failed variables' type changed to int in the debugger. Here is the screenshot. enter image description here

Why does this happen?

Is there anything wrong in my compiler?

I tried to decompile another class but things were ok.

enter image description here

My IDEA version is IntelliJ IDEA 2021.2 (Ultimate Edition) Build #IU-212.4746.92, built on July 27, 2021

chaos
  • 1,359
  • 2
  • 13
  • 25
  • Well that's quite strange. Perhaps an IDE issue? What version of IntelliJ are you using? Is there an [MCVE](https://stackoverflow.com/help/minimal-reproducible-example) of this issue you can provide for others to run? – Rogue Aug 09 '22 at 12:46
  • 0 is false in boolean logic. Could just be a ide display issue. – markfila Aug 09 '22 at 12:51
  • @markfila I tried to evaluate expression in debugger, and it says that `failed` is not a boolean. – chaos Aug 09 '22 at 16:09
  • Does this answer your question? [IntelliJ "Debug info unavailable" - how to fix?](https://stackoverflow.com/questions/1539282/intellij-debug-info-unavailable-how-to-fix) – Rogue Aug 10 '22 at 14:46
  • Note the comment in your debugger above the variables: "Variables debug info not available". This is a recent issue in either Java or IntelliJ 2021.2. – Rogue Aug 10 '22 at 14:47

1 Answers1

1

Because JVM.

Java-the-language has booleans. The JVM (Java-the-bytecode, Java-the-bytecode-runner) mostly doesn't. There are ways to convey that e.g. a method's return type is boolean, so booleans exist when describing the signatures of things, but the runtime model does not have them. For example, if we look at the full list of all bytecode instructions and we scan for e.g. the xLOAD instruction, there's:

  • aload, which loads references
  • dload which loads doubles
  • fload which loads floats
  • iload which loads ints
  • lload which loads longs

That's it. There is no bload or zload to load a boolean, because they don't exist. They do exist when loading off of arrays. This makes some sense: You wouldn't want a new byte[100] to take up 400 bytes of memory because each byte has to be as large as an int. However, for a single field or local variable, the amount of CPU time you'd waste trying to cajole the CPU, which is fundamentally a 64-bit based concept, into working on chunks of a word, vastly exceeds any gain you'd have by being 'efficient' with your locals. So, just a local var boolean b; takes 64 bits, even though it could have fit in just 1.

The various auto-generated notes in the code added by the debugger refer to all this. At the bytecode level, Local variables do not exist either - instead, there are 'slots' and javac is free to reuse. For example, this code:

void foo() {
  int x = 5;
  System.out.println(x);
  int y = 10;
  System.out.println(y);
}

will compile down to just one slot (given that x is no longer used when you declare y, why not reuse the slot?), or possibly even zero slots as these can just be translated to an ICONST instruction + an invoke.

That's what Slot_5 is all about.

What does a 'slot' hold? well, a reference, an int, a long, a float, or a double. That's it. It cannot hold booleans, shorts, bytes, or chars, because those do not exist. javac rewrites boolean logic to 0/1-based int logic.

And the debugger is just following along with that. Possibly the debugger is a bit 'lost', it's job is to translate what the bytecode is doing back to track as close as possible with the source it has.

There's certainly nothing wrong with your compiler. I doubt there's anything "wrong" with your debugger, other than that it simply isn't as advanced as it could be.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • Per the last line, I think this would more likely be an issue with a (recent or ancient) copy of IntelliJ, as it has translated the boolean values correctly in the debugger display for about as long as I've used it (since 2013 for IntelliJ). – Rogue Aug 09 '22 at 12:57