11
votes

Opcodes illégaux dans la JVM

J'ai récemment rencontré lors du développement d'une bibliothèque qui effectue des opérations sur JVM Bytecode certains opcodes sur lesquels il n'y a pas de documentation (que j'ai trouvée), qui sont encore reconnues par la mise en œuvre de la référence JVM. J'ai trouvé une liste de ceux-ci, et ils sont:

Exception in thread "main" java.lang.VerifyError: Bad instruction: cc
Exception Details:
  Location:
    Test.main([Ljava/lang/String;)V @9: fast_bgetfield
  Reason:
    Error exists in the bytecode
  Bytecode:
    0000000: bb00 0559 b700 064c 2bcc 07b6 0008 572b
    0000010: b200 09b6 000a 5710 0ab8 000b 08b8 000c
    0000020: 8860 aa00 0000 0032 0000 0001 0000 0003
    0000030: 0000 001a 0000 0022 0000 002a b200 0d12
    0000040: 0eb6 000f b200 0d12 10b6 000f b200 0d12
    0000050: 11b6 000f bb00 1259 2bb6 0013 b700 14b8
    0000060: 0015 a700 104d 2cb6 0016 b200 0d12 17b6
    0000070: 000f b1
  Exception Handler Table:
    bci [84, 98] => handler: 101
  Stackmap Table:
    append_frame(@60,Object[#41])
    same_frame(@68)
    same_frame(@76)
    same_frame(@84)
    same_locals_1_stack_item_frame(@101,Object[#42])
    same_frame(@114)

        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
        at java.lang.Class.getMethod0(Unknown Source)
        at java.lang.Class.getMethod(Unknown Source)
        at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)


0 commentaires

3 Réponses :


4
votes

Je ne connais pas tous les opcodes que vous avez énumérés, mais trois d'entre eux- Point d'arrêt , impdep1 , et impdep2 - sont des opcodes réservés documentés dans Section 6.2 de La spécification de la machine virtuelle Java . Il dit, en partie:

Deux des opérations réservés, chiffres 254 (0XFE) et 255 (0xFF), ont les mnémoniques impdep1 et impdep2 , respectivement. Ces instructions sont destinées à fournir des "portes arrière" ou des pièges à des fonctionnalités spécifiques à la mise en œuvre implémentées dans des logiciels et du matériel, respectivement. Le troisième opcode réservé, numéro 202 (0xca), a le mnémonique breakpoint et est destiné à être utilisé par debuggers pour mettre en œuvre des points d'arrêt.

Bien que ces opcodes aient été réservées, elles ne peuvent être utilisées que dans une mise en oeuvre de la machine virtuelle Java. Ils ne peuvent pas apparaître dans des fichiers de classe valides. . . .

Je suppose (de leurs noms) que le reste des autres opcodes fait partie du mécanisme JIT et ne peut pas apparaître dans un fichier de classe valide.


0 commentaires

3
votes

Ces opcodes sont réservés et ne peuvent pas apparaître dans un fichier de classe valide, d'où le VerifyErrorRor. Cependant, la JVM les utilise en interne. Par conséquent, la représentation en mémoire de certains bypodes peut contenir ces opérations après modification par la machine virtuelle. Cependant, c'est purement un détail de mise en œuvre.


0 commentaires

13
votes

La première édition de la spécification de la machine virtuelle Java décrit une technique utilisée par l'une des premières implémentations de Sun de la machine virtuelle Java pour accélérer l'interprétation des bytecodes. Dans ce schéma, les opcodes qui se réfèrent à des entrées de piscine constantes sont remplacées par un opcode "_Quick" lorsque l'entrée de pool constante est résolue. Lorsque la machine virtuelle rencontre une instruction _Quick, elle sait que l'entrée de la piscine constante est déjà résolue et peut donc exécuter l'instruction plus rapidement.

L'ensemble d'instructions de base de la machine virtuelle Java est composé de 200 opcodes mono-octets. Ces 200 opcodes sont les seuls opcodes que vous verrez jamais dans les fichiers de classe. Mise en œuvre de la machine virtuelle qui utilise la technique "_Quick" utilise un autre opcode monocoly-octet en interne, les opcodes "_Quick".

Par exemple, lorsqu'une machine virtuelle utilisant la technique _Quick résout une entrée de pool constante mentionnée par une instruction LDC (valeur OPCODE 0x12), elle remplace l'octet OPCODE LDC dans le flux de bytecode avec une instruction LDC_Quick (valeur OPCODE 0XCB ). Cette technique fait partie du processus de remplacement d'une référence symbolique avec une référence directe dans la machine virtuelle précoce de Sun.

Pour quelques instructions, en plus d'écraser l'opcode normal avec un opcode _Quick, une machine virtuelle qui utilise la technique _Quick écrase les opérandes de l'instruction avec des données qui représentent la référence directe. Par exemple, en plus du remplacement d'un opcode invokeVirtual avec un requênvirtual_quick, la machine virtuelle place également le décalage de la table de méthode et le nombre d'arguments dans les deux octets d'opérande qui suivent toutes les instructions invoombes. Placer le décalage de la table de méthode dans le flux de bytecode à la suite de l'opcode InvokeVirtual_Quick Sauvegarde la machine virtuelle l'heure à laquelle il faudrait pour rechercher le décalage dans l'entrée de piscine constante résolue.

Chapitre 8 de l'intérieur de la machine virtuelle Java

Fondamentalement, vous ne pouvez pas simplement mettre l'opcode dans le fichier de classe. Seul le JVM peut le faire après avoir résolu les opérandes.


0 commentaires