标签: jvm-bytecode

Dalvik 字节码中的“抛出”和“异常注释”

为什么字节码生成为

 .annotation system Ldalvik/annotation/Throws;
        value = {
            Ljava/io/FileNotFoundException;
        }
 .end annotation
Run Code Online (Sandbox Code Playgroud)

而不是.throws Ljava/io/FileNotFoundException

throws FileNotFoundException如果一个方法在java代码的标头中声明?

android dalvik jasmin java-bytecode-asm jvm-bytecode

5
推荐指数
1
解决办法
807
查看次数

Java字节码签名

作为我正在编写的编程语言的编译器的一部分,我在字节码中遇到了通用签名,我试图解析并转换为AST.解析算法大多数都有效,但似乎有一种特殊情况,这些签名的格式有点奇怪.以下是一些这样的情况:

java.util.Arrays#parallelSort: <T::Ljava/lang/Comparable<-TT;>;>([TT;)V
java.util.Arrays#parallelSort: <T::Ljava/lang/Comparable<-TT;>;>([TT;II)V
java.lang.Class#getAnnotation: <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
java.lang.Class#getAnnotationsByType: <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)[TA;
java.lang.Class#getDeclaredAnnotation: <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
java.lang.Class#getDeclaredAnnotationsByType: <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)[TA;
java.util.Arrays#parallelSort: <T::Ljava/lang/Comparable<-TT;>;>([TT;)V
java.util.Arrays#parallelSort: <T::Ljava/lang/Comparable<-TT;>;>([TT;II)V
java.util.Collections#sort: <T::Ljava/lang/Comparable<-TT;>;>(Ljava/util/List<TT;>;)V
Run Code Online (Sandbox Code Playgroud)

在这些类中的所有方法中,这些是唯一具有::签名的方法.我的问题是这个令牌的作用以及它存在的原因.

编辑

我知道Java语言中::运算符,但这是字节码级别的内容.

java generics jvm method-signature jvm-bytecode

5
推荐指数
1
解决办法
978
查看次数

为JVM编写语言

假设我写了一种编程语言;对于同名,我将其称为lang

为了开始编写lang的漫长旅程,我决定从自己编写lang开始。我实际上不能运行它,因为没有什么可以运行自己运行的程序。

因此,我首先使用Java 为lang编写另一个编译器。这次,当我完成后,我决定将其转换为Bytecode,然后保留它。我现在有一个正在运行的编译器,它将把我所有的lang代码转换为Bytecode。

因此,我决定将自己的语言编译器插入我刚用Java编写的编译器中。然后,我将自编译器转换为Bytecode,然后剔除Java编译器。现在,我有了一个纯粹由自己编写的lang编译器,可以将其转换为Bytecode,以备使用。

这样就创建了一个可靠的程序,我理解了所有这些内容,但是我的问题是,相对于JVM的编译器设计,如果决定发布针对该语言的更新该怎么办?我该如何更新字节码?我是否只用旧版本重写了该语言的更新版本?

我问这是因为这是我想要做的。自己编写一种不存在的语言,然后通过首先使用Java创建编译器将其引导到JVM。

这与使用C ++所做的相同。先编写带有类的C,然后再编写C ++,最后,将带有类的C替换为自举的C ++。但是他们到底是怎么更新语言的呢?

java compiler-construction jvm jvm-bytecode

5
推荐指数
1
解决办法
189
查看次数

为什么没有ICMP指令?

正如你们中的一些人可能知道的那样,我们有大量的操作码来比较不同类型的原始值:

LCMP
FCMPL
FCMPG
DCMPL
DCMPG
IFEQ
IFNE
IFLT
IFGE
IFGT
IFLE
IF_ICMPEQ
IF_ICMPNE
IF_ICMPLT
IF_ICMPGE
IF_ICMPGT
IF_ICMPLE
IF_ACMPEQ
IF_ACMPNE
...
Run Code Online (Sandbox Code Playgroud)

由于显而易见的原因,指令集的创建者并没有费心去添加所有IF_LCMPEQ,IF_FCMPLT...指令,但我想知道为什么没有ICMP指令,看到它对于布尔值或者非常有用Integer.compare(int, int).

java jvm jvm-bytecode

4
推荐指数
1
解决办法
472
查看次数

可以将同步块简化为字节码级别的Try-Finally块吗?

编写我自己的编译器用于类似Java的语言,我在编译时遇到了问题synchronized blocks.我提出了以下想法,将它们简化为try-finally块:

synchonized (obj) {
     statements...
}
Run Code Online (Sandbox Code Playgroud)

可以替换

Object _lock = obj
_monitorEnter(lock)
try {
    statements...
}
finally {
    _monitorExit(lock)
}
Run Code Online (Sandbox Code Playgroud)

在哪里_monitorEnter_monitorExit代表MONITORENTERMONITOREXIT说明.

我对这个如何synchronized编译的假设是正确的,还是我错过了什么?

编辑

我以前的实现对机构内部的一些特殊处理returnthrow声明.基本上,它会在每个或指令之前手动加载所有lock变量.这是由块处理,还是我还需要这些检查?MONITOREXIT*RETURNTHROWfinally

java bytecode synchronized try-finally jvm-bytecode

4
推荐指数
1
解决办法
359
查看次数

AOT仪器是什么意思?

我知道字节码检测是什么。它只是在运行时更改 .class 文件字节码,这似乎自 JDK 1.5 以来可用。但是,据说是在类加载期间而不是在运行时。

现在我的问题是,什么是 AOT 或 Ahead of Time 仪器?什么是相反的程序?随着时间的推移仪器?

检测您的代码
Quasar 光纤依赖于字节码检测。这可以在类加载时通过 完成Java Agent,或者在编译时使用 Ant 任务完成。

运行检测
Java 代理Quasar的轻量级线程实现依赖于字节码检测。检测可以在编译时(详见下文)或运行时使用 Java 代理执行。要运行 Java 代理,必须将以下内容添加到 java 命令行(或使用您喜欢的构建工具将其添加为 JVM 参数):

-javaagent:path-to-quasar-jar.jar

提前 (AOT)
检测 使用 Quasar 检测程序的简单且可取的方法是使用 Java 代理,它在运行时检测代码。然而,有时运行 Java 代理不是一种选择。

Quasar 通过 Ant 任务支持 AOT 检测。该任务位于 co.paralleluniverse.fibers.instrument.InstrumentationTaskquasar-core.jar,它接受要检测的类文件集。并不是所有的类都会被实际检测——只有那些带有 suspendable methods(见下文)的类——所以只需将程序中的所有类文件交给任务即可。事实上,Quasar 本身是 提前检测的

来源

java instrumentation bytecode quasar jvm-bytecode

4
推荐指数
1
解决办法
612
查看次数

ASM 中的 ClassWriter COMPUTE_FRAMES

我一直试图通过玩转 ASM 中的跳转来了解堆栈映射框架在 Java 中的工作原理。我创建了一个简单的方法来尝试一些东西:(用 Krakatau 拆卸):

    L0:     ldc 'hello' 
    L2:     astore_1 
    L3:     getstatic Field java/lang/System out Ljava/io/PrintStream; 
    L6:     new java/lang/StringBuilder 
    L9:     dup 
    L10:    invokespecial Method java/lang/StringBuilder <init> ()V 
    L13:    ldc 'concat1' 
    L15:    invokevirtual Method java/lang/StringBuilder append (Ljava/lang/String;)Ljava/lang/StringBuilder; 
    L18:    aload_1 
    L19:    invokevirtual Method java/lang/StringBuilder append (Ljava/lang/String;)Ljava/lang/StringBuilder; 
    L22:    invokevirtual Method java/lang/StringBuilder toString ()Ljava/lang/String; 
    L25:    invokevirtual Method java/io/PrintStream println (Ljava/lang/String;)V 
    L28:    getstatic Field java/lang/System out Ljava/io/PrintStream; 
    L31:    new java/lang/StringBuilder 
    L34:    dup 
    L35:    invokespecial Method java/lang/StringBuilder <init> ()V 
    L38:    ldc 'concat2' 
    L40:    invokevirtual …
Run Code Online (Sandbox Code Playgroud)

java bytecode-manipulation java-bytecode-asm jvm-bytecode

4
推荐指数
1
解决办法
698
查看次数

为什么 Java 1.0.2 中的接口 Member 没有设置 ACC_ABSTRACT?

我编写了一个简单的 Java 字节码解析器来进行一些实验,最近它在一个意想不到的地方失败了。在读取java/lang/reflect/Member.javaJava 1.1.8.16时rt.jar,我的解析器很生气,因为Member它是这样开始的(注意缺少ACC_ABSTRACT标志):

\n\n
Classfile Member.class\n  Last modified Aug 8, 2002; size 350 bytes\n  MD5 checksum 9a1aaec8e70e9a2ff9d63331cb0ea34e\n  Compiled from "Member.java"\npublic interface java.lang.reflect.Member\n  minor version: 3\n  major version: 45\n  flags: (0x0201) ACC_PUBLIC, ACC_INTERFACE\n...\n
Run Code Online (Sandbox Code Playgroud)\n\n

Java 1.2.2.17 的版本更正了这一点,并将标志设置为0x0601( ACC_ABSTRACT | ACC_INTERFACE | ACC_PUBLIC)。

\n\n

我能找到的最早的 JVM 规范(据称是 1.0.2)有这样的说法(\xc2\xa74.1,p.\xc2\xa086,强调):

\n\n
\n

接口是隐式抽象的 (\xc2\xa72.13.1);必须设置ACC_ABSTRACT\xef\xac\x82ag 。接口不可能是最终的;如果是的话,它的实现永远无法完成(\xc2\xa72.13.1),因此它无法设置其\xef\xac\x82ag。ACC_FINAL

\n
\n\n

JVM 规范第 9 版也有类似的话

\n\n
\n

如果ACC_INTERFACE …

java jvm bytecode .class-file jvm-bytecode

4
推荐指数
1
解决办法
110
查看次数

java JVM 字节码表示法,注释语法。调用动态

问题:第14行是什么意思?

使用 javap -v -c 反汇编以下代码:

 public class test {
     static int i = 2;
     public static void main(String[] args) {
         test x = new test();
         System.out.println("text + String: " + i);
     } 
 }
Run Code Online (Sandbox Code Playgroud)

在主函数中,我们得到以下内容:

14: invokedynamic #20,  0             // InvokeDynamic #0:makeConcatWithConstants:(I)Ljava/lang/String;
19: invokevirtual #24                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
...
BootstrapMethods:
  0: #38 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #44 text + String: \u0001
Run Code Online (Sandbox Code Playgroud)

因此,例如,第 19 行表示来自运行时常量池中 #24 项的 invokevirtual 函数。调用的方法println()来自于类java/io/PrintStream,其输入来自于类Ljava/lang/String,其返回值为 Void。

至于第 14 行,#0 持有对 BootstrapMethod …

java jvm javap jvm-bytecode

4
推荐指数
1
解决办法
145
查看次数

为什么COMPUTE_FRAMES会产生大量冗余指令?

我正在编写一个输出 JVM 字节代码的编译器,并使用 ASM 9.4 作为后端。这工作得很好,但我对一个特殊的怪癖感到困惑。

我指定COMPUTE_FRAMES自动计算堆栈帧。据说,这种权衡是(可以理解)这使得代码生成需要更多时间,但它似乎足够快。

我能找到的任何地方都没有记录,指定COMPUTE_FRAMES会导致生成大量冗余指令。具体来说,athrow每个方法末尾都有一个 ,并且在某些情况下,一堆长运行的nops 分散在该方法中。

这似乎并没有造成任何伤害;我最初的测试用例顺利通过,我想 JIT 编译器实际上不会为冗余指令生成任何机器代码。但这有点令人不安。它为什么要这样做?我做错了什么吗?

java java-bytecode-asm jvm-bytecode

4
推荐指数
1
解决办法
67
查看次数