Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
0bea3bc6
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
0bea3bc6
编写于
8月 26, 2014
作者:
A
asaha
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
aebaa21c
6dfc52e9
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
207 addition
and
47 deletion
+207
-47
.hgtags
.hgtags
+1
-0
src/share/vm/classfile/stackMapFrame.cpp
src/share/vm/classfile/stackMapFrame.cpp
+0
-15
src/share/vm/classfile/stackMapFrame.hpp
src/share/vm/classfile/stackMapFrame.hpp
+0
-4
src/share/vm/classfile/stackMapTable.cpp
src/share/vm/classfile/stackMapTable.cpp
+0
-13
src/share/vm/classfile/stackMapTable.hpp
src/share/vm/classfile/stackMapTable.hpp
+0
-4
src/share/vm/classfile/verifier.cpp
src/share/vm/classfile/verifier.cpp
+192
-9
src/share/vm/classfile/verifier.hpp
src/share/vm/classfile/verifier.hpp
+11
-0
test/runtime/7116786/Test7116786.java
test/runtime/7116786/Test7116786.java
+3
-2
未找到文件。
.hgtags
浏览文件 @
0bea3bc6
...
@@ -515,4 +515,5 @@ f3f50c4f9ea5d3af40cb794b6f3f2a337c8873db jdk8u25-b08
...
@@ -515,4 +515,5 @@ f3f50c4f9ea5d3af40cb794b6f3f2a337c8873db jdk8u25-b08
9e2bb00a81910776d5b16c49a3f4c5264ceab522 jdk8u25-b11
9e2bb00a81910776d5b16c49a3f4c5264ceab522 jdk8u25-b11
2993491d47df8c4b096ea7fa534162bde8b53dcf jdk8u25-b12
2993491d47df8c4b096ea7fa534162bde8b53dcf jdk8u25-b12
ca6d25be853b5c428c6228871316671843264666 jdk8u25-b13
ca6d25be853b5c428c6228871316671843264666 jdk8u25-b13
c77d5db189422e2eef0443ee212644e497113b18 jdk8u25-b14
5bb683bbe2c74876d585b5c3232fc3aab7b23e97 jdk8u31-b00
5bb683bbe2c74876d585b5c3232fc3aab7b23e97 jdk8u31-b00
src/share/vm/classfile/stackMapFrame.cpp
浏览文件 @
0bea3bc6
...
@@ -54,21 +54,6 @@ StackMapFrame* StackMapFrame::frame_in_exception_handler(u1 flags) {
...
@@ -54,21 +54,6 @@ StackMapFrame* StackMapFrame::frame_in_exception_handler(u1 flags) {
return
frame
;
return
frame
;
}
}
bool
StackMapFrame
::
has_new_object
()
const
{
int32_t
i
;
for
(
i
=
0
;
i
<
_max_locals
;
i
++
)
{
if
(
_locals
[
i
].
is_uninitialized
())
{
return
true
;
}
}
for
(
i
=
0
;
i
<
_stack_size
;
i
++
)
{
if
(
_stack
[
i
].
is_uninitialized
())
{
return
true
;
}
}
return
false
;
}
void
StackMapFrame
::
initialize_object
(
void
StackMapFrame
::
initialize_object
(
VerificationType
old_object
,
VerificationType
new_object
)
{
VerificationType
old_object
,
VerificationType
new_object
)
{
int32_t
i
;
int32_t
i
;
...
...
src/share/vm/classfile/stackMapFrame.hpp
浏览文件 @
0bea3bc6
...
@@ -154,10 +154,6 @@ class StackMapFrame : public ResourceObj {
...
@@ -154,10 +154,6 @@ class StackMapFrame : public ResourceObj {
VerificationType
set_locals_from_arg
(
VerificationType
set_locals_from_arg
(
const
methodHandle
m
,
VerificationType
thisKlass
,
TRAPS
);
const
methodHandle
m
,
VerificationType
thisKlass
,
TRAPS
);
// Search local variable type array and stack type array.
// Return true if an uninitialized object is found.
bool
has_new_object
()
const
;
// Search local variable type array and stack type array.
// Search local variable type array and stack type array.
// Set every element with type of old_object to new_object.
// Set every element with type of old_object to new_object.
void
initialize_object
(
void
initialize_object
(
...
...
src/share/vm/classfile/stackMapTable.cpp
浏览文件 @
0bea3bc6
...
@@ -130,19 +130,6 @@ void StackMapTable::check_jump_target(
...
@@ -130,19 +130,6 @@ void StackMapTable::check_jump_target(
if
(
!
match
||
(
target
<
0
||
target
>=
_code_length
))
{
if
(
!
match
||
(
target
<
0
||
target
>=
_code_length
))
{
frame
->
verifier
()
->
verify_error
(
ctx
,
frame
->
verifier
()
->
verify_error
(
ctx
,
"Inconsistent stackmap frames at branch target %d"
,
target
);
"Inconsistent stackmap frames at branch target %d"
,
target
);
return
;
}
// check if uninitialized objects exist on backward branches
check_new_object
(
frame
,
target
,
CHECK_VERIFY
(
frame
->
verifier
()));
}
void
StackMapTable
::
check_new_object
(
const
StackMapFrame
*
frame
,
int32_t
target
,
TRAPS
)
const
{
if
(
frame
->
offset
()
>
target
&&
frame
->
has_new_object
())
{
frame
->
verifier
()
->
verify_error
(
ErrorContext
::
bad_code
(
frame
->
offset
()),
"Uninitialized object exists on backward branch %d"
,
target
);
return
;
}
}
}
}
...
...
src/share/vm/classfile/stackMapTable.hpp
浏览文件 @
0bea3bc6
...
@@ -90,10 +90,6 @@ class StackMapTable : public StackObj {
...
@@ -90,10 +90,6 @@ class StackMapTable : public StackObj {
// Returns the frame array index where the frame with offset is stored.
// Returns the frame array index where the frame with offset is stored.
int
get_index_from_offset
(
int32_t
offset
)
const
;
int
get_index_from_offset
(
int32_t
offset
)
const
;
// Make sure that there's no uninitialized object exist on backward branch.
void
check_new_object
(
const
StackMapFrame
*
frame
,
int32_t
target
,
TRAPS
)
const
;
void
print_on
(
outputStream
*
str
)
const
;
void
print_on
(
outputStream
*
str
)
const
;
};
};
...
...
src/share/vm/classfile/verifier.cpp
浏览文件 @
0bea3bc6
...
@@ -2231,6 +2231,181 @@ void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
...
@@ -2231,6 +2231,181 @@ void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
}
}
}
}
// Look at the method's handlers. If the bci is in the handler's try block
// then check if the handler_pc is already on the stack. If not, push it.
void
ClassVerifier
::
push_handlers
(
ExceptionTable
*
exhandlers
,
GrowableArray
<
u4
>*
handler_stack
,
u4
bci
)
{
int
exlength
=
exhandlers
->
length
();
for
(
int
x
=
0
;
x
<
exlength
;
x
++
)
{
if
(
bci
>=
exhandlers
->
start_pc
(
x
)
&&
bci
<
exhandlers
->
end_pc
(
x
))
{
handler_stack
->
append_if_missing
(
exhandlers
->
handler_pc
(
x
));
}
}
}
// Return TRUE if all code paths starting with start_bc_offset end in
// bytecode athrow or loop.
bool
ClassVerifier
::
ends_in_athrow
(
u4
start_bc_offset
)
{
ResourceMark
rm
;
// Create bytecode stream.
RawBytecodeStream
bcs
(
method
());
u4
code_length
=
method
()
->
code_size
();
bcs
.
set_start
(
start_bc_offset
);
u4
target
;
// Create stack for storing bytecode start offsets for if* and *switch.
GrowableArray
<
u4
>*
bci_stack
=
new
GrowableArray
<
u4
>
(
30
);
// Create stack for handlers for try blocks containing this handler.
GrowableArray
<
u4
>*
handler_stack
=
new
GrowableArray
<
u4
>
(
30
);
// Create list of visited branch opcodes (goto* and if*).
GrowableArray
<
u4
>*
visited_branches
=
new
GrowableArray
<
u4
>
(
30
);
ExceptionTable
exhandlers
(
_method
());
while
(
true
)
{
if
(
bcs
.
is_last_bytecode
())
{
// if no more starting offsets to parse or if at the end of the
// method then return false.
if
((
bci_stack
->
is_empty
())
||
((
u4
)
bcs
.
end_bci
()
==
code_length
))
return
false
;
// Pop a bytecode starting offset and scan from there.
bcs
.
set_start
(
bci_stack
->
pop
());
}
Bytecodes
::
Code
opcode
=
bcs
.
raw_next
();
u4
bci
=
bcs
.
bci
();
// If the bytecode is in a TRY block, push its handlers so they
// will get parsed.
push_handlers
(
&
exhandlers
,
handler_stack
,
bci
);
switch
(
opcode
)
{
case
Bytecodes
::
_if_icmpeq
:
case
Bytecodes
::
_if_icmpne
:
case
Bytecodes
::
_if_icmplt
:
case
Bytecodes
::
_if_icmpge
:
case
Bytecodes
::
_if_icmpgt
:
case
Bytecodes
::
_if_icmple
:
case
Bytecodes
::
_ifeq
:
case
Bytecodes
::
_ifne
:
case
Bytecodes
::
_iflt
:
case
Bytecodes
::
_ifge
:
case
Bytecodes
::
_ifgt
:
case
Bytecodes
::
_ifle
:
case
Bytecodes
::
_if_acmpeq
:
case
Bytecodes
::
_if_acmpne
:
case
Bytecodes
::
_ifnull
:
case
Bytecodes
::
_ifnonnull
:
target
=
bcs
.
dest
();
if
(
visited_branches
->
contains
(
bci
))
{
if
(
bci_stack
->
is_empty
())
return
true
;
// Pop a bytecode starting offset and scan from there.
bcs
.
set_start
(
bci_stack
->
pop
());
}
else
{
if
(
target
>
bci
)
{
// forward branch
if
(
target
>=
code_length
)
return
false
;
// Push the branch target onto the stack.
bci_stack
->
push
(
target
);
// then, scan bytecodes starting with next.
bcs
.
set_start
(
bcs
.
next_bci
());
}
else
{
// backward branch
// Push bytecode offset following backward branch onto the stack.
bci_stack
->
push
(
bcs
.
next_bci
());
// Check bytecodes starting with branch target.
bcs
.
set_start
(
target
);
}
// Record target so we don't branch here again.
visited_branches
->
append
(
bci
);
}
break
;
case
Bytecodes
::
_goto
:
case
Bytecodes
::
_goto_w
:
target
=
(
opcode
==
Bytecodes
::
_goto
?
bcs
.
dest
()
:
bcs
.
dest_w
());
if
(
visited_branches
->
contains
(
bci
))
{
if
(
bci_stack
->
is_empty
())
return
true
;
// Been here before, pop new starting offset from stack.
bcs
.
set_start
(
bci_stack
->
pop
());
}
else
{
if
(
target
>=
code_length
)
return
false
;
// Continue scanning from the target onward.
bcs
.
set_start
(
target
);
// Record target so we don't branch here again.
visited_branches
->
append
(
bci
);
}
break
;
// Check that all switch alternatives end in 'athrow' bytecodes. Since it
// is difficult to determine where each switch alternative ends, parse
// each switch alternative until either hit a 'return', 'athrow', or reach
// the end of the method's bytecodes. This is gross but should be okay
// because:
// 1. tableswitch and lookupswitch byte codes in handlers for ctor explicit
// constructor invocations should be rare.
// 2. if each switch alternative ends in an athrow then the parsing should be
// short. If there is no athrow then it is bogus code, anyway.
case
Bytecodes
::
_lookupswitch
:
case
Bytecodes
::
_tableswitch
:
{
address
aligned_bcp
=
(
address
)
round_to
((
intptr_t
)(
bcs
.
bcp
()
+
1
),
jintSize
);
u4
default_offset
=
Bytes
::
get_Java_u4
(
aligned_bcp
)
+
bci
;
int
keys
,
delta
;
if
(
opcode
==
Bytecodes
::
_tableswitch
)
{
jint
low
=
(
jint
)
Bytes
::
get_Java_u4
(
aligned_bcp
+
jintSize
);
jint
high
=
(
jint
)
Bytes
::
get_Java_u4
(
aligned_bcp
+
2
*
jintSize
);
// This is invalid, but let the regular bytecode verifier
// report this because the user will get a better error message.
if
(
low
>
high
)
return
true
;
keys
=
high
-
low
+
1
;
delta
=
1
;
}
else
{
keys
=
(
int
)
Bytes
::
get_Java_u4
(
aligned_bcp
+
jintSize
);
delta
=
2
;
}
// Invalid, let the regular bytecode verifier deal with it.
if
(
keys
<
0
)
return
true
;
// Push the offset of the next bytecode onto the stack.
bci_stack
->
push
(
bcs
.
next_bci
());
// Push the switch alternatives onto the stack.
for
(
int
i
=
0
;
i
<
keys
;
i
++
)
{
u4
target
=
bci
+
(
jint
)
Bytes
::
get_Java_u4
(
aligned_bcp
+
(
3
+
i
*
delta
)
*
jintSize
);
if
(
target
>
code_length
)
return
false
;
bci_stack
->
push
(
target
);
}
// Start bytecode parsing for the switch at the default alternative.
if
(
default_offset
>
code_length
)
return
false
;
bcs
.
set_start
(
default_offset
);
break
;
}
case
Bytecodes
::
_return
:
return
false
;
case
Bytecodes
::
_athrow
:
{
if
(
bci_stack
->
is_empty
())
{
if
(
handler_stack
->
is_empty
())
{
return
true
;
}
else
{
// Parse the catch handlers for try blocks containing athrow.
bcs
.
set_start
(
handler_stack
->
pop
());
}
}
else
{
// Pop a bytecode offset and starting scanning from there.
bcs
.
set_start
(
bci_stack
->
pop
());
}
}
break
;
default:
;
}
// end switch
}
// end while loop
return
false
;
}
void
ClassVerifier
::
verify_invoke_init
(
void
ClassVerifier
::
verify_invoke_init
(
RawBytecodeStream
*
bcs
,
u2
ref_class_index
,
VerificationType
ref_class_type
,
RawBytecodeStream
*
bcs
,
u2
ref_class_index
,
VerificationType
ref_class_type
,
StackMapFrame
*
current_frame
,
u4
code_length
,
bool
*
this_uninit
,
StackMapFrame
*
current_frame
,
u4
code_length
,
bool
*
this_uninit
,
...
@@ -2250,18 +2425,26 @@ void ClassVerifier::verify_invoke_init(
...
@@ -2250,18 +2425,26 @@ void ClassVerifier::verify_invoke_init(
return
;
return
;
}
}
// Make sure that this call is not done from within a TRY block because
// Check if this call is done from inside of a TRY block. If so, make
// that can result in returning an incomplete object. Simply checking
// sure that all catch clause paths end in a throw. Otherwise, this
// (bci >= start_pc) also ensures that this call is not done after a TRY
// can result in returning an incomplete object.
// block. That is also illegal because this call must be the first Java
// statement in the constructor.
ExceptionTable
exhandlers
(
_method
());
ExceptionTable
exhandlers
(
_method
());
int
exlength
=
exhandlers
.
length
();
int
exlength
=
exhandlers
.
length
();
for
(
int
i
=
0
;
i
<
exlength
;
i
++
)
{
for
(
int
i
=
0
;
i
<
exlength
;
i
++
)
{
if
(
bci
>=
exhandlers
.
start_pc
(
i
))
{
u2
start_pc
=
exhandlers
.
start_pc
(
i
);
verify_error
(
ErrorContext
::
bad_code
(
bci
),
u2
end_pc
=
exhandlers
.
end_pc
(
i
);
"Bad <init> method call from after the start of a try block"
);
return
;
if
(
bci
>=
start_pc
&&
bci
<
end_pc
)
{
if
(
!
ends_in_athrow
(
exhandlers
.
handler_pc
(
i
)))
{
verify_error
(
ErrorContext
::
bad_code
(
bci
),
"Bad <init> method call from after the start of a try block"
);
return
;
}
else
if
(
VerboseVerification
)
{
ResourceMark
rm
;
tty
->
print_cr
(
"Survived call to ends_in_athrow(): %s"
,
current_class
()
->
name
()
->
as_C_string
());
}
}
}
}
}
...
...
src/share/vm/classfile/verifier.hpp
浏览文件 @
0bea3bc6
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include "oops/klass.hpp"
#include "oops/klass.hpp"
#include "oops/method.hpp"
#include "oops/method.hpp"
#include "runtime/handles.hpp"
#include "runtime/handles.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/exceptions.hpp"
// The verifier class
// The verifier class
...
@@ -303,6 +304,16 @@ class ClassVerifier : public StackObj {
...
@@ -303,6 +304,16 @@ class ClassVerifier : public StackObj {
StackMapFrame
*
current_frame
,
u4
code_length
,
bool
*
this_uninit
,
StackMapFrame
*
current_frame
,
u4
code_length
,
bool
*
this_uninit
,
constantPoolHandle
cp
,
TRAPS
);
constantPoolHandle
cp
,
TRAPS
);
// Used by ends_in_athrow() to push all handlers that contain bci onto
// the handler_stack, if the handler is not already on the stack.
void
push_handlers
(
ExceptionTable
*
exhandlers
,
GrowableArray
<
u4
>*
handler_stack
,
u4
bci
);
// Returns true if all paths starting with start_bc_offset end in athrow
// bytecode or loop.
bool
ends_in_athrow
(
u4
start_bc_offset
);
void
verify_invoke_instructions
(
void
verify_invoke_instructions
(
RawBytecodeStream
*
bcs
,
u4
code_length
,
StackMapFrame
*
current_frame
,
RawBytecodeStream
*
bcs
,
u4
code_length
,
StackMapFrame
*
current_frame
,
bool
*
this_uninit
,
VerificationType
return_type
,
bool
*
this_uninit
,
VerificationType
return_type
,
...
...
test/runtime/7116786/Test7116786.java
浏览文件 @
0bea3bc6
/*
/*
* Copyright (c) 2012, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 201
4
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -147,7 +147,8 @@ class VerifyErrorCases {
...
@@ -147,7 +147,8 @@ class VerifyErrorCases {
"no stackmap frame at jump location or bad jump"
,
"no stackmap frame at jump location or bad jump"
,
"Inconsistent stackmap frames at branch target "
),
"Inconsistent stackmap frames at branch target "
),
new
Case
(
"case15"
,
"stackMapTable.cpp"
,
true
,
"check_new_object"
,
/* Backward jump with uninit is allowed starting with JDK 8 */
new
Case
(
"case15"
,
"stackMapTable.cpp"
,
false
,
"check_new_object"
,
"backward jump with uninit"
,
"backward jump with uninit"
,
"Uninitialized object exists on backward branch "
),
"Uninitialized object exists on backward branch "
),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录