Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JVM bytecode limitations on class-class interactions

Tags:

java

jvm

bytecode

I was looking through the JVM bytecode instructions and was surprised to see that all the interactions between classes (e.g. casting, new, etc.) rely upon constant pool lookups for identity of the other classes.

Am I correct in inferring that this means that one class cannot know about the existence of more than 64k others, as it is impossible to refer to them? If one did need to refer to that many, what ought one do--delegate the work to multiple classes each of which could have their own <64k interactions?

(The reason this interests me is that I have a habit of writing code generators, sometimes producing thousands of distinct classes, and that some languages (e.g. Scala) create classes prolifically. So it seems that if true I have to be careful: if I have hundreds of methods in a class each using hundreds of (distinct) classes, I could exceed the constant pool space.)

like image 879
Rex Kerr Avatar asked May 04 '13 15:05

Rex Kerr


People also ask

What is opcodes in Java?

A Java Virtual Machine instruction consists of an opcode specifying the operation to be performed, followed by zero or more operands embodying values to be operated upon. This chapter gives details about the format of each Java Virtual Machine instruction and the operation it performs.

How is Java bytecode executed?

They can be executed by intepretation, just-in-time compiling, or any other technique that was chosen by the designer of a particular JVM. A method's bytecode stream is a sequence of instructions for the Java virtual machine. Each instruction consists of a one-byte opcode followed by zero or more operands.

Does JVM have registers?

The JVM has a program counter and three registers that manage the stack. It has few registers because the bytecode instructions of the JVM operate primarily on the stack. This stack-oriented design helps keep the JVM's instruction set and implementation small.

What is LDC in Java?

It is Load Constant. It loads an item from the constant pool onto the stack.


2 Answers

Am I correct in inferring that this means that one class cannot know about the existence of more than 64k others, as it is impossible to refer to them?

I think you are correct. And don't forget that there are constant pool entries for other things; e.g. all of the classes method and fields names, and all of its literal strings.

If one did need to refer to that many, what ought one do--delegate the work to multiple classes each of which could have their own <64k interactions?

I guess so.

However, I'm not convinced that this concern would ever be realized in practice. It is hard to conceive of a class that needs to directly interact with that many other classes ... unless the code generator is ignoring the structure of its input source code.

like image 78
Stephen C Avatar answered Oct 20 '22 08:10

Stephen C


It sounds like your problem could be solved via invokedynamic. This is basically a much faster form of reflection designed to ease the implementation of dynamic languages on the JVM.

If you really do have to deal with thousands of automatically generated classes, you probably don't want to statically link it all. Just use invokedynamic. This also has the advantage of letting you defer some code generation to runtime.

Note that you still need a constant pool entry for every dynamic method called by a class, but you no longer need to refer to the actual class and methods being called. In fact, you can create them on demand.

like image 39
Antimony Avatar answered Oct 20 '22 09:10

Antimony