Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
f6c6b615
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看板
提交
f6c6b615
编写于
12月 13, 2016
作者:
C
coleenp
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8168699: Validate special case invocations
Reviewed-by: kevinw, vlivanov
上级
619b0ce8
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
169 addition
and
42 deletion
+169
-42
src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
+6
-1
src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
+6
-1
src/share/vm/c1/c1_CodeStubs.hpp
src/share/vm/c1/c1_CodeStubs.hpp
+3
-1
src/share/vm/c1/c1_GraphBuilder.cpp
src/share/vm/c1/c1_GraphBuilder.cpp
+14
-0
src/share/vm/c1/c1_Instruction.hpp
src/share/vm/c1/c1_Instruction.hpp
+11
-0
src/share/vm/ci/ciInstanceKlass.cpp
src/share/vm/ci/ciInstanceKlass.cpp
+13
-1
src/share/vm/ci/ciInstanceKlass.hpp
src/share/vm/ci/ciInstanceKlass.hpp
+8
-1
src/share/vm/ci/ciMethod.cpp
src/share/vm/ci/ciMethod.cpp
+8
-1
src/share/vm/ci/ciMethod.hpp
src/share/vm/ci/ciMethod.hpp
+2
-1
src/share/vm/interpreter/interpreterRuntime.cpp
src/share/vm/interpreter/interpreterRuntime.cpp
+12
-2
src/share/vm/interpreter/linkResolver.cpp
src/share/vm/interpreter/linkResolver.cpp
+35
-16
src/share/vm/interpreter/linkResolver.hpp
src/share/vm/interpreter/linkResolver.hpp
+4
-4
src/share/vm/oops/cpCache.cpp
src/share/vm/oops/cpCache.cpp
+13
-5
src/share/vm/oops/cpCache.hpp
src/share/vm/oops/cpCache.hpp
+4
-2
src/share/vm/opto/doCall.cpp
src/share/vm/opto/doCall.cpp
+25
-1
src/share/vm/prims/methodHandles.cpp
src/share/vm/prims/methodHandles.cpp
+3
-3
src/share/vm/runtime/javaCalls.cpp
src/share/vm/runtime/javaCalls.cpp
+2
-2
未找到文件。
src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
浏览文件 @
f6c6b615
...
...
@@ -1023,11 +1023,16 @@ void LIRGenerator::do_CheckCast(CheckCast* x) {
obj
.
load_item
();
LIR_Opr
out_reg
=
rlock_result
(
x
);
CodeStub
*
stub
;
CodeEmitInfo
*
info_for_exception
=
state_for
(
x
);
CodeEmitInfo
*
info_for_exception
=
(
x
->
needs_exception_state
()
?
state_for
(
x
)
:
state_for
(
x
,
x
->
state_before
(),
true
/*ignore_xhandler*/
));
if
(
x
->
is_incompatible_class_change_check
())
{
assert
(
patching_info
==
NULL
,
"can't patch this"
);
stub
=
new
SimpleExceptionStub
(
Runtime1
::
throw_incompatible_class_change_error_id
,
LIR_OprFact
::
illegalOpr
,
info_for_exception
);
}
else
if
(
x
->
is_invokespecial_receiver_check
())
{
assert
(
patching_info
==
NULL
,
"can't patch this"
);
stub
=
new
DeoptimizeStub
(
info_for_exception
);
}
else
{
stub
=
new
SimpleExceptionStub
(
Runtime1
::
throw_class_cast_exception_id
,
obj
.
result
(),
info_for_exception
);
}
...
...
src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
浏览文件 @
f6c6b615
...
...
@@ -1228,12 +1228,17 @@ void LIRGenerator::do_CheckCast(CheckCast* x) {
obj
.
load_item
();
// info for exceptions
CodeEmitInfo
*
info_for_exception
=
state_for
(
x
);
CodeEmitInfo
*
info_for_exception
=
(
x
->
needs_exception_state
()
?
state_for
(
x
)
:
state_for
(
x
,
x
->
state_before
(),
true
/*ignore_xhandler*/
));
CodeStub
*
stub
;
if
(
x
->
is_incompatible_class_change_check
())
{
assert
(
patching_info
==
NULL
,
"can't patch this"
);
stub
=
new
SimpleExceptionStub
(
Runtime1
::
throw_incompatible_class_change_error_id
,
LIR_OprFact
::
illegalOpr
,
info_for_exception
);
}
else
if
(
x
->
is_invokespecial_receiver_check
())
{
assert
(
patching_info
==
NULL
,
"can't patch this"
);
stub
=
new
DeoptimizeStub
(
info_for_exception
);
}
else
{
stub
=
new
SimpleExceptionStub
(
Runtime1
::
throw_class_cast_exception_id
,
obj
.
result
(),
info_for_exception
);
}
...
...
src/share/vm/c1/c1_CodeStubs.hpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 1999, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -57,6 +57,7 @@ class CodeStub: public CompilationResourceObj {
virtual
bool
is_exception_throw_stub
()
const
{
return
false
;
}
virtual
bool
is_range_check_stub
()
const
{
return
false
;
}
virtual
bool
is_divbyzero_stub
()
const
{
return
false
;
}
virtual
bool
is_simple_exception_stub
()
const
{
return
false
;
}
#ifndef PRODUCT
virtual
void
print_name
(
outputStream
*
out
)
const
=
0
;
#endif
...
...
@@ -484,6 +485,7 @@ class SimpleExceptionStub: public CodeStub {
virtual
void
emit_code
(
LIR_Assembler
*
e
);
virtual
CodeEmitInfo
*
info
()
const
{
return
_info
;
}
virtual
bool
is_exception_throw_stub
()
const
{
return
true
;
}
virtual
bool
is_simple_exception_stub
()
const
{
return
true
;
}
virtual
void
visit
(
LIR_OpVisitState
*
visitor
)
{
if
(
_obj
->
is_valid
())
visitor
->
do_input
(
_obj
);
visitor
->
do_slow_case
(
_info
);
...
...
src/share/vm/c1/c1_GraphBuilder.cpp
浏览文件 @
f6c6b615
...
...
@@ -1823,6 +1823,20 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
log
->
identify
(
target
),
Bytecodes
::
name
(
code
));
// invoke-special-super
if
(
bc_raw
==
Bytecodes
::
_invokespecial
&&
!
target
->
is_object_initializer
())
{
ciInstanceKlass
*
sender_klass
=
calling_klass
->
is_anonymous
()
?
calling_klass
->
host_klass
()
:
calling_klass
;
if
(
sender_klass
->
is_interface
())
{
int
index
=
state
()
->
stack_size
()
-
(
target
->
arg_size_no_receiver
()
+
1
);
Value
receiver
=
state
()
->
stack_at
(
index
);
CheckCast
*
c
=
new
CheckCast
(
sender_klass
,
receiver
,
copy_state_before
());
c
->
set_invokespecial_receiver_check
();
state
()
->
stack_at_put
(
index
,
append_split
(
c
));
}
}
// Some methods are obviously bindable without any type checks so
// convert them directly to an invokespecial or invokestatic.
if
(
target
->
is_loaded
()
&&
!
target
->
is_abstract
()
&&
target
->
can_be_statically_bound
())
{
...
...
src/share/vm/c1/c1_Instruction.hpp
浏览文件 @
f6c6b615
...
...
@@ -381,6 +381,7 @@ class Instruction: public CompilationResourceObj {
UnorderedIsTrueFlag
,
NeedsPatchingFlag
,
ThrowIncompatibleClassChangeErrorFlag
,
InvokeSpecialReceiverCheckFlag
,
ProfileMDOFlag
,
IsLinkedInBlockFlag
,
NeedsRangeCheckFlag
,
...
...
@@ -1456,6 +1457,16 @@ LEAF(CheckCast, TypeCheck)
bool
is_incompatible_class_change_check
()
const
{
return
check_flag
(
ThrowIncompatibleClassChangeErrorFlag
);
}
void
set_invokespecial_receiver_check
()
{
set_flag
(
InvokeSpecialReceiverCheckFlag
,
true
);
}
bool
is_invokespecial_receiver_check
()
const
{
return
check_flag
(
InvokeSpecialReceiverCheckFlag
);
}
virtual
bool
needs_exception_state
()
const
{
return
!
is_invokespecial_receiver_check
();
}
ciType
*
declared_type
()
const
;
}
;
...
...
src/share/vm/ci/ciInstanceKlass.cpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 1999, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -58,6 +58,7 @@ ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
_nonstatic_field_size
=
ik
->
nonstatic_field_size
();
_has_nonstatic_fields
=
ik
->
has_nonstatic_fields
();
_has_default_methods
=
ik
->
has_default_methods
();
_is_anonymous
=
ik
->
is_anonymous
();
_nonstatic_fields
=
NULL
;
// initialized lazily by compute_nonstatic_fields:
_implementor
=
NULL
;
// we will fill these lazily
...
...
@@ -100,6 +101,7 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
_nonstatic_field_size
=
-
1
;
_has_nonstatic_fields
=
false
;
_nonstatic_fields
=
NULL
;
_is_anonymous
=
false
;
_loader
=
loader
;
_protection_domain
=
protection_domain
;
_is_shared
=
false
;
...
...
@@ -591,6 +593,16 @@ ciInstanceKlass* ciInstanceKlass::implementor() {
return
impl
;
}
ciInstanceKlass
*
ciInstanceKlass
::
host_klass
()
{
assert
(
is_loaded
(),
"must be loaded"
);
if
(
is_anonymous
())
{
VM_ENTRY_MARK
Klass
*
host_klass
=
get_instanceKlass
()
->
host_klass
();
return
CURRENT_ENV
->
get_instance_klass
(
host_klass
);
}
return
NULL
;
}
// Utility class for printing of the contents of the static fields for
// use by compilation replay. It only prints out the information that
// could be consumed by the compiler, so for primitive types it prints
...
...
src/share/vm/ci/ciInstanceKlass.hpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 1999, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -53,6 +53,7 @@ private:
bool
_has_subklass
;
bool
_has_nonstatic_fields
;
bool
_has_default_methods
;
bool
_is_anonymous
;
ciFlags
_flags
;
jint
_nonstatic_field_size
;
...
...
@@ -177,6 +178,10 @@ public:
return
_has_default_methods
;
}
bool
is_anonymous
()
{
return
_is_anonymous
;
}
ciInstanceKlass
*
get_canonical_holder
(
int
offset
);
ciField
*
get_field_by_offset
(
int
field_offset
,
bool
is_static
);
ciField
*
get_field_by_name
(
ciSymbol
*
name
,
ciSymbol
*
signature
,
bool
is_static
);
...
...
@@ -248,6 +253,8 @@ public:
return
NULL
;
}
ciInstanceKlass
*
host_klass
();
// Dump the current state of this klass for compilation replay.
virtual
void
dump_replay_data
(
outputStream
*
out
);
};
...
...
src/share/vm/ci/ciMethod.cpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 1999, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -947,6 +947,13 @@ bool ciMethod::is_compiled_lambda_form() const {
return
iid
==
vmIntrinsics
::
_compiledLambdaForm
;
}
// ------------------------------------------------------------------
// ciMethod::is_object_initializer
//
bool
ciMethod
::
is_object_initializer
()
const
{
return
name
()
==
ciSymbol
::
object_initializer_name
();
}
// ------------------------------------------------------------------
// ciMethod::has_member_arg
//
...
...
src/share/vm/ci/ciMethod.hpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 1999, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -316,6 +316,7 @@ class ciMethod : public ciMetadata {
bool
can_be_statically_bound
()
const
{
return
_can_be_statically_bound
;
}
bool
is_boxing_method
()
const
;
bool
is_unboxing_method
()
const
;
bool
is_object_initializer
()
const
;
// Replay data methods
void
dump_name_as_ascii
(
outputStream
*
st
);
...
...
src/share/vm/interpreter/interpreterRuntime.cpp
浏览文件 @
f6c6b615
...
...
@@ -690,7 +690,8 @@ IRT_END
IRT_ENTRY
(
void
,
InterpreterRuntime
::
resolve_invoke
(
JavaThread
*
thread
,
Bytecodes
::
Code
bytecode
))
{
// extract receiver from the outgoing argument list if necessary
Handle
receiver
(
thread
,
NULL
);
if
(
bytecode
==
Bytecodes
::
_invokevirtual
||
bytecode
==
Bytecodes
::
_invokeinterface
)
{
if
(
bytecode
==
Bytecodes
::
_invokevirtual
||
bytecode
==
Bytecodes
::
_invokeinterface
||
bytecode
==
Bytecodes
::
_invokespecial
)
{
ResourceMark
rm
(
thread
);
methodHandle
m
(
thread
,
method
(
thread
));
Bytecode_invoke
call
(
m
,
bci
(
thread
));
...
...
@@ -756,16 +757,25 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
int
index
=
info
.
resolved_method
()
->
itable_index
();
assert
(
info
.
itable_index
()
==
index
,
""
);
}
}
else
if
(
bytecode
==
Bytecodes
::
_invokespecial
)
{
assert
(
info
.
call_kind
()
==
CallInfo
::
direct_call
,
"must be direct call"
);
}
else
{
assert
(
info
.
call_kind
()
==
CallInfo
::
direct_call
||
info
.
call_kind
()
==
CallInfo
::
vtable_call
,
""
);
}
#endif
// Get sender or sender's host_klass, and only set cpCache entry to resolved if
// it is not an interface. The receiver for invokespecial calls within interface
// methods must be checked for every call.
InstanceKlass
*
sender
=
pool
->
pool_holder
();
sender
=
sender
->
is_anonymous
()
?
InstanceKlass
::
cast
(
sender
->
host_klass
())
:
sender
;
switch
(
info
.
call_kind
())
{
case
CallInfo
::
direct_call
:
cache_entry
(
thread
)
->
set_direct_call
(
bytecode
,
info
.
resolved_method
());
info
.
resolved_method
(),
sender
->
is_interface
());
break
;
case
CallInfo
::
vtable_call
:
cache_entry
(
thread
)
->
set_vtable_call
(
...
...
src/share/vm/interpreter/linkResolver.cpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 1997, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -913,11 +913,11 @@ void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method,
}
void
LinkResolver
::
resolve_special_call
(
CallInfo
&
result
,
KlassHandle
resolved_klass
,
Symbol
*
method_name
,
void
LinkResolver
::
resolve_special_call
(
CallInfo
&
result
,
Handle
recv
,
KlassHandle
resolved_klass
,
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
bool
check_access
,
TRAPS
)
{
methodHandle
resolved_method
;
linktime_resolve_special_method
(
resolved_method
,
resolved_klass
,
method_name
,
method_signature
,
current_klass
,
check_access
,
CHECK
);
runtime_resolve_special_method
(
result
,
resolved_method
,
resolved_klass
,
current_klass
,
check_access
,
CHECK
);
runtime_resolve_special_method
(
result
,
resolved_method
,
resolved_klass
,
current_klass
,
recv
,
check_access
,
CHECK
);
}
// throws linktime exceptions
...
...
@@ -1016,7 +1016,7 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method
// throws runtime exceptions
void
LinkResolver
::
runtime_resolve_special_method
(
CallInfo
&
result
,
methodHandle
resolved_method
,
KlassHandle
resolved_klass
,
KlassHandle
current_klass
,
bool
check_access
,
TRAPS
)
{
KlassHandle
current_klass
,
Handle
recv
,
bool
check_access
,
TRAPS
)
{
// resolved method is selected method unless we have an old-style lookup
// for a superclass method
...
...
@@ -1024,21 +1024,19 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle
// no checks for shadowing
methodHandle
sel_method
(
THREAD
,
resolved_method
());
// check if this is an old-style super call and do a new lookup if so
{
KlassHandle
method_klass
=
KlassHandle
(
THREAD
,
resolved_method
->
method_holder
());
if
(
check_access
&&
// check if the method is not <init>
resolved_method
->
name
()
!=
vmSymbols
::
object_initializer_name
())
{
if
(
check_access
&&
// check if this is an old-style super call and do a new lookup if so
// a) check if ACC_SUPER flag is set for the current class
(
current_klass
->
is_super
()
||
!
AllowNonVirtualCalls
)
&&
if
(
(
current_klass
->
is_super
()
||
!
AllowNonVirtualCalls
)
&&
// b) check if the class of the resolved_klass is a superclass
// (not supertype in order to exclude interface classes) of the current class.
// This check is not performed for super.invoke for interface methods
// in super interfaces.
current_klass
->
is_subclass_of
(
resolved_klass
())
&&
current_klass
()
!=
resolved_klass
()
&&
// c) check if the method is not <init>
resolved_method
->
name
()
!=
vmSymbols
::
object_initializer_name
())
{
current_klass
()
!=
resolved_klass
())
{
// Lookup super method
KlassHandle
super_klass
(
THREAD
,
current_klass
->
super
());
lookup_instance_method_in_klasses
(
sel_method
,
super_klass
,
...
...
@@ -1053,6 +1051,27 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle
resolved_method
->
signature
()));
}
}
// Check that the class of objectref (the receiver) is the current class or interface,
// or a subtype of the current class or interface (the sender), otherwise invokespecial
// throws IllegalAccessError.
// The verifier checks that the sender is a subtype of the class in the I/MR operand.
// The verifier also checks that the receiver is a subtype of the sender, if the sender is
// a class. If the sender is an interface, the check has to be performed at runtime.
InstanceKlass
*
sender
=
InstanceKlass
::
cast
(
current_klass
());
sender
=
sender
->
is_anonymous
()
?
InstanceKlass
::
cast
(
sender
->
host_klass
())
:
sender
;
if
(
sender
->
is_interface
()
&&
recv
.
not_null
())
{
Klass
*
receiver_klass
=
recv
->
klass
();
if
(
!
receiver_klass
->
is_subtype_of
(
sender
))
{
ResourceMark
rm
(
THREAD
);
char
buf
[
500
];
jio_snprintf
(
buf
,
sizeof
(
buf
),
"Receiver class %s must be the current class or a subtype of interface %s"
,
receiver_klass
->
name
()
->
as_C_string
(),
sender
->
name
()
->
as_C_string
());
THROW_MSG
(
vmSymbols
::
java_lang_IllegalAccessError
(),
buf
);
}
}
}
// check if not static
...
...
@@ -1479,7 +1498,7 @@ methodHandle LinkResolver::resolve_special_call_or_null(
bool
check_access
)
{
EXCEPTION_MARK
;
CallInfo
info
;
resolve_special_call
(
info
,
resolved_klass
,
name
,
signature
,
current_klass
,
check_access
,
THREAD
);
resolve_special_call
(
info
,
Handle
(),
resolved_klass
,
name
,
signature
,
current_klass
,
check_access
,
THREAD
);
if
(
HAS_PENDING_EXCEPTION
)
{
CLEAR_PENDING_EXCEPTION
;
return
methodHandle
();
...
...
@@ -1495,7 +1514,7 @@ methodHandle LinkResolver::resolve_special_call_or_null(
void
LinkResolver
::
resolve_invoke
(
CallInfo
&
result
,
Handle
recv
,
constantPoolHandle
pool
,
int
index
,
Bytecodes
::
Code
byte
,
TRAPS
)
{
switch
(
byte
)
{
case
Bytecodes
::
_invokestatic
:
resolve_invokestatic
(
result
,
pool
,
index
,
CHECK
);
break
;
case
Bytecodes
::
_invokespecial
:
resolve_invokespecial
(
result
,
pool
,
index
,
CHECK
);
break
;
case
Bytecodes
::
_invokespecial
:
resolve_invokespecial
(
result
,
recv
,
pool
,
index
,
CHECK
);
break
;
case
Bytecodes
::
_invokevirtual
:
resolve_invokevirtual
(
result
,
recv
,
pool
,
index
,
CHECK
);
break
;
case
Bytecodes
::
_invokehandle
:
resolve_invokehandle
(
result
,
pool
,
index
,
CHECK
);
break
;
case
Bytecodes
::
_invokedynamic
:
resolve_invokedynamic
(
result
,
pool
,
index
,
CHECK
);
break
;
...
...
@@ -1526,13 +1545,13 @@ void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle poo
}
void
LinkResolver
::
resolve_invokespecial
(
CallInfo
&
result
,
constantPoolHandle
pool
,
int
index
,
TRAPS
)
{
void
LinkResolver
::
resolve_invokespecial
(
CallInfo
&
result
,
Handle
recv
,
constantPoolHandle
pool
,
int
index
,
TRAPS
)
{
KlassHandle
resolved_klass
;
Symbol
*
method_name
=
NULL
;
Symbol
*
method_signature
=
NULL
;
KlassHandle
current_klass
;
resolve_pool
(
resolved_klass
,
method_name
,
method_signature
,
current_klass
,
pool
,
index
,
CHECK
);
resolve_special_call
(
result
,
resolved_klass
,
method_name
,
method_signature
,
current_klass
,
true
,
CHECK
);
resolve_special_call
(
result
,
re
cv
,
re
solved_klass
,
method_name
,
method_signature
,
current_klass
,
true
,
CHECK
);
}
...
...
src/share/vm/interpreter/linkResolver.hpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 1997, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -142,7 +142,7 @@ class LinkResolver: AllStatic {
static
void
linktime_resolve_virtual_method
(
methodHandle
&
resolved_method
,
KlassHandle
resolved_klass
,
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
bool
check_access
,
TRAPS
);
static
void
linktime_resolve_interface_method
(
methodHandle
&
resolved_method
,
KlassHandle
resolved_klass
,
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
bool
check_access
,
TRAPS
);
static
void
runtime_resolve_special_method
(
CallInfo
&
result
,
methodHandle
resolved_method
,
KlassHandle
resolved_klass
,
KlassHandle
current_klass
,
bool
check_access
,
TRAPS
);
static
void
runtime_resolve_special_method
(
CallInfo
&
result
,
methodHandle
resolved_method
,
KlassHandle
resolved_klass
,
KlassHandle
current_klass
,
Handle
recv
,
bool
check_access
,
TRAPS
);
static
void
runtime_resolve_virtual_method
(
CallInfo
&
result
,
methodHandle
resolved_method
,
KlassHandle
resolved_klass
,
Handle
recv
,
KlassHandle
recv_klass
,
bool
check_null_and_abstract
,
TRAPS
);
static
void
runtime_resolve_interface_method
(
CallInfo
&
result
,
methodHandle
resolved_method
,
KlassHandle
resolved_klass
,
Handle
recv
,
KlassHandle
recv_klass
,
bool
check_null_and_abstract
,
TRAPS
);
...
...
@@ -173,7 +173,7 @@ class LinkResolver: AllStatic {
// resolved_klass = specified class (i.e., static receiver class)
// current_klass = sending method holder (i.e., class containing the method containing the call being resolved)
static
void
resolve_static_call
(
CallInfo
&
result
,
KlassHandle
&
resolved_klass
,
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
bool
check_access
,
bool
initialize_klass
,
TRAPS
);
static
void
resolve_special_call
(
CallInfo
&
result
,
KlassHandle
resolved_klass
,
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
bool
check_access
,
TRAPS
);
static
void
resolve_special_call
(
CallInfo
&
result
,
Handle
recv
,
KlassHandle
resolved_klass
,
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
bool
check_access
,
TRAPS
);
static
void
resolve_virtual_call
(
CallInfo
&
result
,
Handle
recv
,
KlassHandle
recv_klass
,
KlassHandle
resolved_klass
,
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
bool
check_access
,
bool
check_null_and_abstract
,
TRAPS
);
static
void
resolve_interface_call
(
CallInfo
&
result
,
Handle
recv
,
KlassHandle
recv_klass
,
KlassHandle
resolved_klass
,
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
bool
check_access
,
bool
check_null_and_abstract
,
TRAPS
);
static
void
resolve_handle_call
(
CallInfo
&
result
,
KlassHandle
resolved_klass
,
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
TRAPS
);
...
...
@@ -196,7 +196,7 @@ class LinkResolver: AllStatic {
// runtime resolving from constant pool
static
void
resolve_invokestatic
(
CallInfo
&
result
,
constantPoolHandle
pool
,
int
index
,
TRAPS
);
static
void
resolve_invokespecial
(
CallInfo
&
result
,
constantPoolHandle
pool
,
int
index
,
TRAPS
);
static
void
resolve_invokespecial
(
CallInfo
&
result
,
Handle
recv
,
constantPoolHandle
pool
,
int
index
,
TRAPS
);
static
void
resolve_invokevirtual
(
CallInfo
&
result
,
Handle
recv
,
constantPoolHandle
pool
,
int
index
,
TRAPS
);
static
void
resolve_invokeinterface
(
CallInfo
&
result
,
Handle
recv
,
constantPoolHandle
pool
,
int
index
,
TRAPS
);
static
void
resolve_invokedynamic
(
CallInfo
&
result
,
constantPoolHandle
pool
,
int
index
,
TRAPS
);
...
...
src/share/vm/oops/cpCache.cpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 1998, 201
5
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -144,7 +144,8 @@ void ConstantPoolCacheEntry::set_parameter_size(int value) {
void
ConstantPoolCacheEntry
::
set_direct_or_vtable_call
(
Bytecodes
::
Code
invoke_code
,
methodHandle
method
,
int
vtable_index
)
{
int
vtable_index
,
bool
sender_is_interface
)
{
bool
is_vtable_call
=
(
vtable_index
>=
0
);
// FIXME: split this method on this boolean
assert
(
method
->
interpreter_entry
()
!=
NULL
,
"should have been set at this point"
);
assert
(
!
method
->
is_obsolete
(),
"attempt to write obsolete method to cpCache"
);
...
...
@@ -208,7 +209,13 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
if
(
byte_no
==
1
)
{
assert
(
invoke_code
!=
Bytecodes
::
_invokevirtual
&&
invoke_code
!=
Bytecodes
::
_invokeinterface
,
""
);
// Don't mark invokespecial to method as resolved if sender is an interface. The receiver
// has to be checked that it is a subclass of the current class every time this bytecode
// is executed.
if
(
invoke_code
!=
Bytecodes
::
_invokespecial
||
!
sender_is_interface
||
method
->
name
()
==
vmSymbols
::
object_initializer_name
())
{
set_bytecode_1
(
invoke_code
);
}
}
else
if
(
byte_no
==
2
)
{
if
(
change_to_virtual
)
{
assert
(
invoke_code
==
Bytecodes
::
_invokeinterface
,
""
);
...
...
@@ -238,17 +245,18 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
NOT_PRODUCT
(
verify
(
tty
));
}
void
ConstantPoolCacheEntry
::
set_direct_call
(
Bytecodes
::
Code
invoke_code
,
methodHandle
method
)
{
void
ConstantPoolCacheEntry
::
set_direct_call
(
Bytecodes
::
Code
invoke_code
,
methodHandle
method
,
bool
sender_is_interface
)
{
int
index
=
Method
::
nonvirtual_vtable_index
;
// index < 0; FIXME: inline and customize set_direct_or_vtable_call
set_direct_or_vtable_call
(
invoke_code
,
method
,
index
);
set_direct_or_vtable_call
(
invoke_code
,
method
,
index
,
sender_is_interface
);
}
void
ConstantPoolCacheEntry
::
set_vtable_call
(
Bytecodes
::
Code
invoke_code
,
methodHandle
method
,
int
index
)
{
// either the method is a miranda or its holder should accept the given index
assert
(
method
->
method_holder
()
->
is_interface
()
||
method
->
method_holder
()
->
verify_vtable_index
(
index
),
""
);
// index >= 0; FIXME: inline and customize set_direct_or_vtable_call
set_direct_or_vtable_call
(
invoke_code
,
method
,
index
);
set_direct_or_vtable_call
(
invoke_code
,
method
,
index
,
false
);
}
void
ConstantPoolCacheEntry
::
set_itable_call
(
Bytecodes
::
Code
invoke_code
,
methodHandle
method
,
int
index
)
{
...
...
src/share/vm/oops/cpCache.hpp
浏览文件 @
f6c6b615
...
...
@@ -229,13 +229,15 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
void
set_direct_or_vtable_call
(
Bytecodes
::
Code
invoke_code
,
// the bytecode used for invoking the method
methodHandle
method
,
// the method/prototype if any (NULL, otherwise)
int
vtable_index
// the vtable index if any, else negative
int
vtable_index
,
// the vtable index if any, else negative
bool
sender_is_interface
);
public:
void
set_direct_call
(
// sets entry to exact concrete method entry
Bytecodes
::
Code
invoke_code
,
// the bytecode used for invoking the method
methodHandle
method
// the method to call
methodHandle
method
,
// the method to call
bool
sender_is_interface
);
void
set_vtable_call
(
// sets entry to vtable index
...
...
src/share/vm/opto/doCall.cpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 1998, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -477,6 +477,30 @@ void Parse::do_call() {
speculative_receiver_type
=
receiver_type
!=
NULL
?
receiver_type
->
speculative_type
()
:
NULL
;
}
// invoke-super-special
if
(
iter
().
cur_bc_raw
()
==
Bytecodes
::
_invokespecial
&&
!
orig_callee
->
is_object_initializer
())
{
ciInstanceKlass
*
calling_klass
=
method
()
->
holder
();
ciInstanceKlass
*
sender_klass
=
calling_klass
->
is_anonymous
()
?
calling_klass
->
host_klass
()
:
calling_klass
;
if
(
sender_klass
->
is_interface
())
{
Node
*
receiver_node
=
stack
(
sp
()
-
nargs
);
Node
*
cls_node
=
makecon
(
TypeKlassPtr
::
make
(
sender_klass
));
Node
*
bad_type_ctrl
=
NULL
;
Node
*
casted_receiver
=
gen_checkcast
(
receiver_node
,
cls_node
,
&
bad_type_ctrl
);
if
(
bad_type_ctrl
!=
NULL
)
{
PreserveJVMState
pjvms
(
this
);
set_control
(
bad_type_ctrl
);
uncommon_trap
(
Deoptimization
::
Reason_class_check
,
Deoptimization
::
Action_none
);
}
if
(
stopped
())
{
return
;
// MUST uncommon-trap?
}
set_stack
(
sp
()
-
nargs
,
casted_receiver
);
}
}
// Note: It's OK to try to inline a virtual call.
// The call generator will not attempt to inline a polymorphic call
// unless it knows how to optimize the receiver dispatch.
...
...
src/share/vm/prims/methodHandles.cpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 2008, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -679,7 +679,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
defc
,
name
,
type
,
caller
,
THREAD
);
}
else
if
(
ref_kind
==
JVM_REF_invokeSpecial
)
{
LinkResolver
::
resolve_special_call
(
result
,
defc
,
name
,
type
,
caller
,
caller
.
not_null
(),
THREAD
);
Handle
(),
defc
,
name
,
type
,
caller
,
caller
.
not_null
(),
THREAD
);
}
else
if
(
ref_kind
==
JVM_REF_invokeVirtual
)
{
LinkResolver
::
resolve_virtual_call
(
result
,
Handle
(),
defc
,
defc
,
name
,
type
,
caller
,
caller
.
not_null
(),
false
,
THREAD
);
...
...
@@ -706,7 +706,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
assert
(
!
HAS_PENDING_EXCEPTION
,
""
);
if
(
name
==
vmSymbols
::
object_initializer_name
())
{
LinkResolver
::
resolve_special_call
(
result
,
defc
,
name
,
type
,
caller
,
caller
.
not_null
(),
THREAD
);
Handle
(),
defc
,
name
,
type
,
caller
,
caller
.
not_null
(),
THREAD
);
}
else
{
break
;
// will throw after end of switch
}
...
...
src/share/vm/runtime/javaCalls.cpp
浏览文件 @
f6c6b615
/*
* Copyright (c) 1997, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -231,7 +231,7 @@ void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spe
void
JavaCalls
::
call_special
(
JavaValue
*
result
,
KlassHandle
klass
,
Symbol
*
name
,
Symbol
*
signature
,
JavaCallArguments
*
args
,
TRAPS
)
{
CallInfo
callinfo
;
LinkResolver
::
resolve_special_call
(
callinfo
,
klass
,
name
,
signature
,
KlassHandle
(),
false
,
CHECK
);
LinkResolver
::
resolve_special_call
(
callinfo
,
args
->
receiver
(),
klass
,
name
,
signature
,
KlassHandle
(),
false
,
CHECK
);
methodHandle
method
=
callinfo
.
selected_method
();
assert
(
method
.
not_null
(),
"should have thrown exception"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录