CharacterRangeTable
转载:https://github.com/jacoco/jacoco/wiki/CharacterRangeTable
This page discusses a not yet available feature!
The CharacterRangeTable is a non-standard (not defined in The Java Virtual Machine Specification) optional variable-length attribute in the attributes table of a Code attribute.
Compilers
Can be produced by javac from OracleJDK 1.5 - 1.9 and IBM JDK 1.5 - 1.8 with help of non-standard undocumented option "-Xjcov", which is ignored by Eclipse Compiler.
Support of this attribute is unlikely to disappear soon:
OpenJDK JCov can use it for some scenarios
javap starting from OpenJDK 7 decodes content of this attribute
it receives fixes in recent versions of OpenJDK - JDK-8059453
Format
See com/sun/tools/classfile/CharacterRangeTable_attribute.java
CharacterRangeTable_attribute {
u2 start_pc;
u2 end_pc;
u4 character_range_start;
u4 character_range_end;
u2 flags;
}
Each character_range encodes line and column as following:
line = character_range >> 10 column = character_range & 0x03ff
How can be used
Condition coverage
Ranges with flags CRT_BRANCH_TRUE (0x0080) and CRT_BRANCH_FALSE (0x0100) are of particular interest, because could be used to map bytecode branches back to conditions in source code.
Logical and
package com.test19;
public class Test05 {
void example(int a, int b) {
if (a == 1 && b == 1)
nop();
}
void nop(){};
}
生成的class文件如下:
public class com.test19.Test05
SourceFile: "Test05.java"
Utf8 1533252190610Utf8 1533252242529minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#20 // java/lang/Object."<init>":()V
#2 = Methodref #3.#21 // com/test19/Test05.nop:()V
#3 = Class #22 // com/test19/Test05
#4 = Class #23 // java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Utf8 LineNumberTable
#9 = Utf8 CharacterRangeTable
#10 = Utf8 example
#11 = Utf8 (II)V
#12 = Utf8 StackMapTable
#13 = Utf8 nop
#14 = Utf8 SourceFile
#15 = Utf8 Test05.java
#16 = Utf8 SourceID
#17 = Utf8 1533252190610
#18 = Utf8 CompilationID
#19 = Utf8 1533252242529
#20 = NameAndType #5:#6 // "<init>":()V
#21 = NameAndType #13:#6 // nop:()V
#22 = Utf8 com/test19/Test05
#23 = Utf8 java/lang/Object
{
public com.test19.Test05();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init> ":()V
4: return
LineNumberTable:
line 3: 0
CharacterRangeTable:
void example(int, int);
flags:
Code:
stack=2, locals=3, args_size=3
0: iload_1
1: iconst_1
2: if_icmpne 14
5: iload_2
6: iconst_1
7: if_icmpne 14
10: aload_0
11: invokevirtual #2 // Method nop:()V
14: return
LineNumberTable:
line 5: 0
line 6: 10
line 7: 14
CharacterRangeTable:
0, 1, 1407, 140d, 8 // 0, 1, 5:07, 5:13, flow-controller
2, 4, 1407, 140d, 100 // 2, 4, 5:07, 5:13, branch-false
5, 6, 1411, 1417, 10 // 5, 6, 5:17, 5:23, flow-target
0, 6, 1407, 1417, 8 // 0, 6, 5:07, 5:23, flow-controller
7, 9, 1407, 1417, 100 // 7, 9, 5:07, 5:23, branch-false
10, 13, 1804, 180a, 11 // 10, 13, 6:04, 6:10, statement, flow-target
0, 13, 1403, 180a, 1 // 0, 13, 5:03, 6:10, statement
0, 14, 101d, 1c02, 2 // 0, 14, 4:29, 7:02, block
StackMapTable: number_of_entries = 1
frame_type = 14 /* same */
void nop();
flags:
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 8: 0
CharacterRangeTable:
0, 0, 200c, 200d, 2 // 0, 0, 8:12, 8:13, block
}
if branch 2 was taken, then condition 3:09-3:15 (a == 1) evaluates to false,
if branch 7 was taken, then condition 3:09-3:25 (a == 1 && b == 1) evaluates to false.
Logical or
package com.test19;
public class Test05 {
void example(int a, int b) {
if (a == 1 || b == 1) {
nop();
}
}
void nop() {}
}

public class com.test19.Test05
SourceFile: "Test05.java"
Utf8 1533253036302Utf8 1533253190932minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#20 // java/lang/Object."<init>":()V
#2 = Methodref #3.#21 // com/test19/Test05.nop:()V
#3 = Class #22 // com/test19/Test05
#4 = Class #23 // java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Utf8 LineNumberTable
#9 = Utf8 CharacterRangeTable
#10 = Utf8 example
#11 = Utf8 (II)V
#12 = Utf8 StackMapTable
#13 = Utf8 nop
#14 = Utf8 SourceFile
#15 = Utf8 Test05.java
#16 = Utf8 SourceID
#17 = Utf8 1533253036302
#18 = Utf8 CompilationID
#19 = Utf8 1533253190932
#20 = NameAndType #5:#6 // "<init>":()V
#21 = NameAndType #13:#6 // nop:()V
#22 = Utf8 com/test19/Test05
#23 = Utf8 java/lang/Object
{
public com.test19.Test05();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init> ":()V
4: return
LineNumberTable:
line 3: 0
CharacterRangeTable:
void example(int, int);
flags:
Code:
stack=2, locals=3, args_size=3
0: iload_1
1: iconst_1
2: if_icmpeq 10
5: iload_2
6: iconst_1
7: if_icmpne 14
10: aload_0
11: invokevirtual #2 // Method nop:()V
14: return
LineNumberTable:
line 5: 0
line 6: 10
line 8: 14
CharacterRangeTable:
0, 1, 1407, 140d, 8 // 0, 1, 5:07, 5:13, flow-controller
2, 4, 1407, 140d, 80 // 2, 4, 5:07, 5:13, branch-true
5, 6, 1411, 1417, 10 // 5, 6, 5:17, 5:23, flow-target
0, 6, 1407, 1417, 8 // 0, 6, 5:07, 5:23, flow-controller
7, 9, 1407, 1417, 100 // 7, 9, 5:07, 5:23, branch-false
10, 13, 1804, 180a, 1 // 10, 13, 6:04, 6:10, statement
10, 13, 1419, 1c03, 13 // 10, 13, 5:25, 7:03, statement, block, flow-target
0, 13, 1403, 1c03, 1 // 0, 13, 5:03, 7:03, statement
0, 14, 101d, 2002, 2 // 0, 14, 4:29, 8:02, block
StackMapTable: number_of_entries = 2
frame_type = 10 /* same */
frame_type = 3 /* same */
void nop();
flags:
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 9: 0
CharacterRangeTable:
0, 0, 240d, 240e, 2 // 0, 0, 9:13, 9:14, blo ck
}
if branch 2 was taken, then condition 3:09-3:15 (a == 1) evaluates to true,
if branch 7 was taken, then condition 3:09-3:25 (a == 1 || b == 1) evaluates to false.
Conditional operator
package com.test19;
public class Test05 {
void example(int a, int b) {
nop(a == 1 ? 2 : 3);
}
void nop(int x) {}
}
public class com.test19.Test05
SourceFile: "Test05.java"
Utf8 1533253525422Utf8 1533253540376minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#22 // java/lang/Object."<init>":()V
#2 = Methodref #3.#23 // com/test19/Test05.nop:(I)V
#3 = Class #24 // com/test19/Test05
#4 = Class #25 // java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Utf8 LineNumberTable
#9 = Utf8 CharacterRangeTable
#10 = Utf8 example
#11 = Utf8 (II)V
#12 = Utf8 StackMapTable
#13 = Class #24 // com/test19/Test05
#14 = Utf8 nop
#15 = Utf8 (I)V
#16 = Utf8 SourceFile
#17 = Utf8 Test05.java
#18 = Utf8 SourceID
#19 = Utf8 1533253525422
#20 = Utf8 CompilationID
#21 = Utf8 1533253540376
#22 = NameAndType #5:#6 // "<init>":()V
#23 = NameAndType #14:#15 // nop:(I)V
#24 = Utf8 com/test19/Test05
#25 = Utf8 java/lang/Object
{
public com.test19.Test05();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
CharacterRangeTable:
void example(int, int);
flags:
Code:
stack=3, locals=3, args_size=3
0: aload_0
1: iload_1
2: iconst_1
3: if_icmpne 10
6: iconst_2
7: goto 11
10: iconst_3
11: invokevirtual #2 // Method nop:(I)V
14: return
LineNumberTable:
line 5: 0
line 6: 14
CharacterRangeTable:
1, 2, 1407, 140d, 8 // 1, 2, 5:07, 5:13, flow-controller
3, 5, 1407, 140d, 100 // 3, 5, 5:07, 5:13, branch-false
6, 6, 1410, 1411, 10 // 6, 6, 5:16, 5:17, flow-target
10, 10, 1414, 1415, 10 // 10, 10, 5:20, 5:21, flow-target
0, 13, 1403, 1417, 1 // 0, 13, 5:03, 5:23, statement
0, 14, 101d, 1802, 2 // 0, 14, 4:29, 6:02, block
StackMapTable: number_of_entries = 2
frame_type = 74 /* same_locals_1_stack_item */
stack = [ class com/test19/Test05 ]
frame_type = 255 /* full_frame */
offset_delta = 0
locals = [ class com/test19/Test05, int, int ]
stack = [ class com/test19/Test05, int ]
void nop(int);
flags:
Code:
stack=0, locals=2, args_size=2
0: return
LineNumberTable:
line 7: 0
CharacterRangeTable:
0, 0, 1c12, 1c13, 2 // 0, 0, 7:18, 7:19, block
}
if branch 2 was taken, then condition 3:09-3:15 (a == 1) evaluates to false.
Filtering
Ranges with flag CRT_BLOCK (0x0002) could be used to filter synthetic compiler constructs.
Duplicated finally blocks
package com.test19;
public class Test05 {
void example() {
try {
nop();
} finally {
nop();
}
}
void nop() {}
}
public class com.test19.Test05
SourceFile: "Test05.java"
Utf8 1533253682139Utf8 1533253727858minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#20 // java/lang/Object."<init>":()V
#2 = Methodref #3.#21 // com/test19/Test05.nop:()V
#3 = Class #22 // com/test19/Test05
#4 = Class #23 // java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Utf8 LineNumberTable
#9 = Utf8 CharacterRangeTable
#10 = Utf8 example
#11 = Utf8 StackMapTable
#12 = Class #24 // java/lang/Throwable
#13 = Utf8 nop
#14 = Utf8 SourceFile
#15 = Utf8 Test05.java
#16 = Utf8 SourceID
#17 = Utf8 1533253682139
#18 = Utf8 CompilationID
#19 = Utf8 1533253727858
#20 = NameAndType #5:#6 // "<init>":()V
#21 = NameAndType #13:#6 // nop:()V
#22 = Utf8 com/test19/Test05
#23 = Utf8 java/lang/Object
#24 = Utf8 java/lang/Throwable
{
public com.test19.Test05();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
CharacterRangeTable:
void example();
flags:
Code:
stack=1, locals=2, args_size=1
0: aload_0
1: invokevirtual #2 // Method nop:()V
4: aload_0
5: invokevirtual #2 // Method nop:()V
8: goto 18
11: astore_1
12: aload_0
13: invokevirtual #2 // Method nop:()V
16: aload_1
17: athrow
18: return
Exception table:
from to target type
0 4 11 any
11 12 11 any
LineNumberTable:
line 6: 0
line 8: 4
line 9: 8
line 8: 11
line 10: 18
CharacterRangeTable:
0, 3, 1804, 180a, 1 // 0, 3, 6:04, 6:10, statement
0, 3, 1407, 1c03, 2 // 0, 3, 5:07, 7:03, block
4, 7, 2004, 200a, 1 // 4, 7, 8:04, 8:10, statement
4, 7, 1c0d, 2403, 2 // 4, 7, 7:13, 9:03, block
12, 15, 2004, 200a, 1 // 12, 15, 8:04, 8:10, statement
12, 15, 1c0d, 2403, 2 // 12, 15, 7:13, 9:03, block
0, 17, 1403, 2403, 1 // 0, 17, 5:03, 9:03, statement
0, 18, 1011, 2802, 2 // 0, 18, 4:17, 10:02, block
StackMapTable: number_of_entries = 2
frame_type = 75 /* same_locals_1_stack_item */
stack = [ class java/lang/Throwable ]
frame_type = 6 /* same */
void nop();
flags:
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 12: 0
CharacterRangeTable:
0, 0, 300d, 300e, 2 // 0, 0, 12:13, 12:14, block
}
same source code corresponds to instructions 3-5 and 10-12.
CharacterRangeTable的更多相关文章
- Gen类的字符串操作
public void t(String d){ final String str = "b"; String s = "a"+"c"+st ...
随机推荐
- 百度Webuploader 大文件分片上传(.net接收)
版权所有 2009-2018荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...
- (转)C#静态方法使用经验浅谈
转自:http://developer.51cto.com/art/200908/147734.htm C#静态方法有什么弊端? 我们在实际的开发过程中会注意到C#静态方法对于我们程序的影响,那么有哪 ...
- 求解1^2+2^2+3^2+4^2+...+n^2的方法(求解1平方加2平方加3平方...加n平方的和)
利用公式 (n-1)3 = n3 -3n2 +3n-1 设 S3 = 13 +23 +33 +43 +...+n3 及 S2 = 12 +22 +32 +42 +...+n2 及 S1 = 1 +2 ...
- Asp.net mvc验证用户登录之Forms实现
这里我们采用asp.net mvc 自带的AuthorizeAttribute过滤器验证用户的身份,也可以使用自定义过滤器,步骤都是一样. 第一步:创建asp.net mvc项目, 在项目的App_S ...
- js 面向对象 继承机制
根据w3cschool上的描述:共有3种继承方法(对象冒充,原型链,混合) 1.对象冒充:构造函数ClassA使用this关键字给所有属性和方法赋值,使ClassA构造函数成为ClassB的方法,调用 ...
- Postgresql 锁查看
之前版本 PostgreSQL 的 pg_stat_activity 视图的 waiting 字段判断会话是否等待锁资源(通俗地讲, waiting 值为true表示申请不到锁资源处于等待状态),但是 ...
- 窗口与导航-----Selenium快速入门(十三)
前面所讲的,大部分是WebDriver这个接口以及相关的类的使用.而本文所讲的窗口与导航,也是里面的内容,而且非常简单,目测就能学会. 一.窗口,也就是window,这里的窗口是指浏览器窗口.他的方法 ...
- NetCore入门篇:(七)Net Core项目使用Controller之二
一.简介 1.说明Post,Get定义的区别. 2.说明如何路由定义. 二.Get.Post定义 1.api不定义访问方式时,同时支持get 和 post.如果定义某种方式,则仅支持某种方式.具体看代 ...
- xt
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- MongoDB VUE的下载及安装
下载: mongo vue官网地址:http://www.mongovue.com/ 安装: 很简单,注意的是:在提示buy 和 OK 的时候点击OK即可: 连接: 默认连接(无用户名密码): 在启 ...