Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
75733dd8
D
dragonwell11
项目概览
openanolis
/
dragonwell11
通知
7
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell11
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
75733dd8
编写于
10月 01, 2012
作者:
T
twisti
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
Reviewed-by: jrose, kvn
上级
dc4794f7
变更
22
隐藏空白更改
内联
并排
Showing
22 changed file
with
358 addition
and
135 deletion
+358
-135
hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
+6
-5
hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
+9
-7
hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
+9
-7
hotspot/src/share/vm/ci/ciClassList.hpp
hotspot/src/share/vm/ci/ciClassList.hpp
+2
-0
hotspot/src/share/vm/ci/ciMethodType.hpp
hotspot/src/share/vm/ci/ciMethodType.hpp
+76
-0
hotspot/src/share/vm/ci/ciObject.hpp
hotspot/src/share/vm/ci/ciObject.hpp
+15
-10
hotspot/src/share/vm/ci/ciObjectFactory.cpp
hotspot/src/share/vm/ci/ciObjectFactory.cpp
+17
-14
hotspot/src/share/vm/ci/ciSignature.cpp
hotspot/src/share/vm/ci/ciSignature.cpp
+19
-0
hotspot/src/share/vm/ci/ciSignature.hpp
hotspot/src/share/vm/ci/ciSignature.hpp
+1
-0
hotspot/src/share/vm/ci/ciStreams.cpp
hotspot/src/share/vm/ci/ciStreams.cpp
+34
-6
hotspot/src/share/vm/ci/ciStreams.hpp
hotspot/src/share/vm/ci/ciStreams.hpp
+8
-6
hotspot/src/share/vm/classfile/systemDictionary.cpp
hotspot/src/share/vm/classfile/systemDictionary.cpp
+6
-2
hotspot/src/share/vm/classfile/systemDictionary.hpp
hotspot/src/share/vm/classfile/systemDictionary.hpp
+2
-0
hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
+2
-0
hotspot/src/share/vm/interpreter/linkResolver.cpp
hotspot/src/share/vm/interpreter/linkResolver.cpp
+21
-12
hotspot/src/share/vm/interpreter/linkResolver.hpp
hotspot/src/share/vm/interpreter/linkResolver.hpp
+8
-6
hotspot/src/share/vm/interpreter/rewriter.cpp
hotspot/src/share/vm/interpreter/rewriter.cpp
+2
-2
hotspot/src/share/vm/interpreter/rewriter.hpp
hotspot/src/share/vm/interpreter/rewriter.hpp
+12
-14
hotspot/src/share/vm/oops/constantPool.cpp
hotspot/src/share/vm/oops/constantPool.cpp
+15
-1
hotspot/src/share/vm/oops/constantPool.hpp
hotspot/src/share/vm/oops/constantPool.hpp
+8
-6
hotspot/src/share/vm/oops/cpCache.cpp
hotspot/src/share/vm/oops/cpCache.cpp
+54
-21
hotspot/src/share/vm/oops/cpCache.hpp
hotspot/src/share/vm/oops/cpCache.hpp
+32
-16
未找到文件。
hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
浏览文件 @
75733dd8
...
...
@@ -2936,6 +2936,7 @@ void TemplateTable::prepare_invoke(int byte_no,
// Push the appendix as a trailing parameter.
// This must be done before we get the receiver,
// since the parameter_size includes it.
assert
(
ConstantPoolCacheEntry
::
_indy_resolved_references_appendix_offset
==
0
,
"appendix expected at index+0"
);
__
load_resolved_reference_at_index
(
temp
,
index
);
__
verify_oop
(
temp
);
__
push_ptr
(
temp
);
// push appendix (MethodType, CallSite, etc.)
...
...
@@ -3235,15 +3236,15 @@ void TemplateTable::invokehandle(int byte_no) {
}
const
Register
Rret
=
Lscratch
;
const
Register
G4_mtype
=
G4_scratch
;
// f1
const
Register
G4_mtype
=
G4_scratch
;
const
Register
O0_recv
=
O0
;
const
Register
Rscratch
=
G3_scratch
;
prepare_invoke
(
byte_no
,
G5_method
,
Rret
,
G4_mtype
,
O0_recv
);
__
null_check
(
O0_recv
);
// G4: MethodType object (from cpool->resolved_references[
]
)
// G5: MH.
linkToCallSite
method (from f2)
// G4: MethodType object (from cpool->resolved_references[
f1], if necessary
)
// G5: MH.
invokeExact_MT
method (from f2)
// Note: G4_mtype is already pushed (if necessary) by prepare_invoke
...
...
@@ -3275,8 +3276,8 @@ void TemplateTable::invokedynamic(int byte_no) {
prepare_invoke
(
byte_no
,
G5_method
,
Rret
,
G4_callsite
);
// G4: CallSite object (from cpool->resolved_references[])
// G5: MH.linkToCallSite method (from f
1
)
// G4: CallSite object (from cpool->resolved_references[
f1
])
// G5: MH.linkToCallSite method (from f
2
)
// Note: G4_callsite is already pushed by prepare_invoke
...
...
hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
浏览文件 @
75733dd8
...
...
@@ -2139,7 +2139,7 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
const
int
index_offset
=
in_bytes
(
ConstantPoolCache
::
base_offset
()
+
ConstantPoolCacheEntry
::
f2_offset
());
size_t
index_size
=
(
is_invokedynamic
?
sizeof
(
u4
)
:
sizeof
(
u2
));
size_t
index_size
=
(
is_invokedynamic
?
sizeof
(
u4
)
:
sizeof
(
u2
));
resolve_cache_and_index
(
byte_no
,
cache
,
index
,
index_size
);
__
movptr
(
method
,
Address
(
cache
,
index
,
Address
::
times_ptr
,
method_offset
));
...
...
@@ -2876,6 +2876,7 @@ void TemplateTable::prepare_invoke(int byte_no,
// since the parameter_size includes it.
__
push
(
rbx
);
__
mov
(
rbx
,
index
);
assert
(
ConstantPoolCacheEntry
::
_indy_resolved_references_appendix_offset
==
0
,
"appendix expected at index+0"
);
__
load_resolved_reference_at_index
(
index
,
rbx
);
__
pop
(
rbx
);
__
push
(
index
);
// push appendix (MethodType, CallSite, etc.)
...
...
@@ -3093,8 +3094,8 @@ void TemplateTable::invokeinterface(int byte_no) {
void
TemplateTable
::
invokehandle
(
int
byte_no
)
{
transition
(
vtos
,
vtos
);
assert
(
byte_no
==
f1_byte
,
"use this argument"
);
const
Register
rbx_method
=
rbx
;
// (from f2)
const
Register
rax_mtype
=
rax
;
// (from f1)
const
Register
rbx_method
=
rbx
;
const
Register
rax_mtype
=
rax
;
const
Register
rcx_recv
=
rcx
;
const
Register
rdx_flags
=
rdx
;
...
...
@@ -3104,13 +3105,14 @@ void TemplateTable::invokehandle(int byte_no) {
return
;
}
prepare_invoke
(
byte_no
,
rbx_method
,
rax_mtype
,
// get f2 Method*, f1 MethodType
rcx_recv
);
prepare_invoke
(
byte_no
,
rbx_method
,
rax_mtype
,
rcx_recv
);
__
verify_method_ptr
(
rbx_method
);
__
verify_oop
(
rcx_recv
);
__
null_check
(
rcx_recv
);
// rax: MethodType object (from cpool->resolved_references[f1], if necessary)
// rbx: MH.invokeExact_MT method (from f2)
// Note: rax_mtype is already pushed (if necessary) by prepare_invoke
// FIXME: profile the LambdaForm also
...
...
@@ -3140,7 +3142,7 @@ void TemplateTable::invokedynamic(int byte_no) {
prepare_invoke
(
byte_no
,
rbx_method
,
rax_callsite
);
// rax: CallSite object (from cpool->resolved_references[])
// rax: CallSite object (from cpool->resolved_references[
f1
])
// rbx: MH.linkToCallSite method (from f2)
// Note: rax_callsite is already pushed by prepare_invoke
...
...
hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
浏览文件 @
75733dd8
...
...
@@ -2184,7 +2184,7 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
const
int
index_offset
=
in_bytes
(
ConstantPoolCache
::
base_offset
()
+
ConstantPoolCacheEntry
::
f2_offset
());
size_t
index_size
=
(
is_invokedynamic
?
sizeof
(
u4
)
:
sizeof
(
u2
));
size_t
index_size
=
(
is_invokedynamic
?
sizeof
(
u4
)
:
sizeof
(
u2
));
resolve_cache_and_index
(
byte_no
,
cache
,
index
,
index_size
);
__
movptr
(
method
,
Address
(
cache
,
index
,
Address
::
times_ptr
,
method_offset
));
...
...
@@ -2926,6 +2926,7 @@ void TemplateTable::prepare_invoke(int byte_no,
// since the parameter_size includes it.
__
push
(
rbx
);
__
mov
(
rbx
,
index
);
assert
(
ConstantPoolCacheEntry
::
_indy_resolved_references_appendix_offset
==
0
,
"appendix expected at index+0"
);
__
load_resolved_reference_at_index
(
index
,
rbx
);
__
pop
(
rbx
);
__
push
(
index
);
// push appendix (MethodType, CallSite, etc.)
...
...
@@ -3144,8 +3145,8 @@ void TemplateTable::invokeinterface(int byte_no) {
void
TemplateTable
::
invokehandle
(
int
byte_no
)
{
transition
(
vtos
,
vtos
);
assert
(
byte_no
==
f1_byte
,
"use this argument"
);
const
Register
rbx_method
=
rbx
;
// f2
const
Register
rax_mtype
=
rax
;
// f1
const
Register
rbx_method
=
rbx
;
const
Register
rax_mtype
=
rax
;
const
Register
rcx_recv
=
rcx
;
const
Register
rdx_flags
=
rdx
;
...
...
@@ -3155,13 +3156,14 @@ void TemplateTable::invokehandle(int byte_no) {
return
;
}
prepare_invoke
(
byte_no
,
rbx_method
,
rax_mtype
,
// get f2 Method*, f1 MethodType
rcx_recv
);
prepare_invoke
(
byte_no
,
rbx_method
,
rax_mtype
,
rcx_recv
);
__
verify_method_ptr
(
rbx_method
);
__
verify_oop
(
rcx_recv
);
__
null_check
(
rcx_recv
);
// rax: MethodType object (from cpool->resolved_references[f1], if necessary)
// rbx: MH.invokeExact_MT method (from f2)
// Note: rax_mtype is already pushed (if necessary) by prepare_invoke
// FIXME: profile the LambdaForm also
...
...
@@ -3191,7 +3193,7 @@ void TemplateTable::invokedynamic(int byte_no) {
prepare_invoke
(
byte_no
,
rbx_method
,
rax_callsite
);
// rax: CallSite object (from cpool->resolved_references[])
// rax: CallSite object (from cpool->resolved_references[
f1
])
// rbx: MH.linkToCallSite method (from f2)
// Note: rax_callsite is already pushed by prepare_invoke
...
...
hotspot/src/share/vm/ci/ciClassList.hpp
浏览文件 @
75733dd8
...
...
@@ -49,6 +49,7 @@ class ciInstance;
class
ciCallSite
;
class
ciMemberName
;
class
ciMethodHandle
;
class
ciMethodType
;
class
ciArray
;
class
ciObjArray
;
class
ciTypeArray
;
...
...
@@ -99,6 +100,7 @@ friend class ciMemberName; \
friend class ciMethod; \
friend class ciMethodData; \
friend class ciMethodHandle; \
friend class ciMethodType; \
friend class ciReceiverTypeData; \
friend class ciSymbol; \
friend class ciArray; \
...
...
hotspot/src/share/vm/ci/ciMethodType.hpp
0 → 100644
浏览文件 @
75733dd8
/*
* Copyright (c) 2012, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_CI_CIMETHODTYPE_HPP
#define SHARE_VM_CI_CIMETHODTYPE_HPP
#include "ci/ciInstance.hpp"
#include "ci/ciUtilities.hpp"
#include "classfile/javaClasses.hpp"
// ciMethodType
//
// The class represents a java.lang.invoke.MethodType object.
class
ciMethodType
:
public
ciInstance
{
private:
ciType
*
class_to_citype
(
oop
klass_oop
)
const
{
if
(
java_lang_Class
::
is_primitive
(
klass_oop
))
{
BasicType
bt
=
java_lang_Class
::
primitive_type
(
klass_oop
);
return
ciType
::
make
(
bt
);
}
else
{
Klass
*
k
=
java_lang_Class
::
as_Klass
(
klass_oop
);
return
CURRENT_ENV
->
get_klass
(
k
);
}
}
public:
ciMethodType
(
instanceHandle
h_i
)
:
ciInstance
(
h_i
)
{}
// What kind of ciObject is this?
bool
is_method_type
()
const
{
return
true
;
}
ciType
*
rtype
()
const
{
GUARDED_VM_ENTRY
(
oop
rtype
=
java_lang_invoke_MethodType
::
rtype
(
get_oop
());
return
class_to_citype
(
rtype
);
)
}
int
ptype_count
()
const
{
GUARDED_VM_ENTRY
(
return
java_lang_invoke_MethodType
::
ptype_count
(
get_oop
());)
}
int
ptype_slot_count
()
const
{
GUARDED_VM_ENTRY
(
return
java_lang_invoke_MethodType
::
ptype_slot_count
(
get_oop
());)
}
ciType
*
ptype_at
(
int
index
)
const
{
GUARDED_VM_ENTRY
(
oop
ptype
=
java_lang_invoke_MethodType
::
ptype
(
get_oop
(),
index
);
return
class_to_citype
(
ptype
);
)
}
};
#endif // SHARE_VM_CI_CIMETHODTYPE_HPP
hotspot/src/share/vm/ci/ciObject.hpp
浏览文件 @
75733dd8
...
...
@@ -123,6 +123,7 @@ public:
virtual
bool
is_instance
()
{
return
false
;
}
virtual
bool
is_member_name
()
const
{
return
false
;
}
virtual
bool
is_method_handle
()
const
{
return
false
;
}
virtual
bool
is_method_type
()
const
{
return
false
;
}
virtual
bool
is_array
()
{
return
false
;
}
virtual
bool
is_obj_array
()
{
return
false
;
}
virtual
bool
is_type_array
()
{
return
false
;
}
...
...
@@ -142,35 +143,39 @@ public:
}
// Subclass casting with assertions.
ciNullObject
*
as_null_object
()
{
ciNullObject
*
as_null_object
()
{
assert
(
is_null_object
(),
"bad cast"
);
return
(
ciNullObject
*
)
this
;
}
ciCallSite
*
as_call_site
()
{
ciCallSite
*
as_call_site
()
{
assert
(
is_call_site
(),
"bad cast"
);
return
(
ciCallSite
*
)
this
;
return
(
ciCallSite
*
)
this
;
}
ciInstance
*
as_instance
()
{
ciInstance
*
as_instance
()
{
assert
(
is_instance
(),
"bad cast"
);
return
(
ciInstance
*
)
this
;
}
ciMemberName
*
as_member_name
()
{
ciMemberName
*
as_member_name
()
{
assert
(
is_member_name
(),
"bad cast"
);
return
(
ciMemberName
*
)
this
;
}
ciMethodHandle
*
as_method_handle
()
{
ciMethodHandle
*
as_method_handle
()
{
assert
(
is_method_handle
(),
"bad cast"
);
return
(
ciMethodHandle
*
)
this
;
return
(
ciMethodHandle
*
)
this
;
}
ciArray
*
as_array
()
{
ciMethodType
*
as_method_type
()
{
assert
(
is_method_type
(),
"bad cast"
);
return
(
ciMethodType
*
)
this
;
}
ciArray
*
as_array
()
{
assert
(
is_array
(),
"bad cast"
);
return
(
ciArray
*
)
this
;
}
ciObjArray
*
as_obj_array
()
{
ciObjArray
*
as_obj_array
()
{
assert
(
is_obj_array
(),
"bad cast"
);
return
(
ciObjArray
*
)
this
;
}
ciTypeArray
*
as_type_array
()
{
ciTypeArray
*
as_type_array
()
{
assert
(
is_type_array
(),
"bad cast"
);
return
(
ciTypeArray
*
)
this
;
}
...
...
hotspot/src/share/vm/ci/ciObjectFactory.cpp
浏览文件 @
75733dd8
...
...
@@ -30,6 +30,7 @@
#include "ci/ciMethod.hpp"
#include "ci/ciMethodData.hpp"
#include "ci/ciMethodHandle.hpp"
#include "ci/ciMethodType.hpp"
#include "ci/ciNullObject.hpp"
#include "ci/ciObjArray.hpp"
#include "ci/ciObjArrayKlass.hpp"
...
...
@@ -237,23 +238,23 @@ ciObject* ciObjectFactory::get(oop key) {
assert
(
key
==
NULL
||
Universe
::
heap
()
->
is_in_reserved
(
key
),
"must be"
);
NonPermObject
*
&
bucket
=
find_non_perm
(
key
);
if
(
bucket
!=
NULL
)
{
return
bucket
->
object
();
}
NonPermObject
*
&
bucket
=
find_non_perm
(
key
);
if
(
bucket
!=
NULL
)
{
return
bucket
->
object
();
}
// The ciObject does not yet exist. Create it and insert it
// into the cache.
Handle
keyHandle
(
key
);
ciObject
*
new_object
=
create_new_object
(
keyHandle
());
assert
(
keyHandle
()
==
new_object
->
get_oop
(),
"must be properly recorded"
);
init_ident_of
(
new_object
);
// The ciObject does not yet exist. Create it and insert it
// into the cache.
Handle
keyHandle
(
key
);
ciObject
*
new_object
=
create_new_object
(
keyHandle
());
assert
(
keyHandle
()
==
new_object
->
get_oop
(),
"must be properly recorded"
);
init_ident_of
(
new_object
);
assert
(
Universe
::
heap
()
->
is_in_reserved
(
new_object
->
get_oop
()),
"must be"
);
// Not a perm-space object.
insert_non_perm
(
bucket
,
keyHandle
(),
new_object
);
return
new_object
;
}
// Not a perm-space object.
insert_non_perm
(
bucket
,
keyHandle
(),
new_object
);
return
new_object
;
}
// ------------------------------------------------------------------
// ciObjectFactory::get
...
...
@@ -324,6 +325,8 @@ ciObject* ciObjectFactory::create_new_object(oop o) {
return
new
(
arena
())
ciMemberName
(
h_i
);
else
if
(
java_lang_invoke_MethodHandle
::
is_instance
(
o
))
return
new
(
arena
())
ciMethodHandle
(
h_i
);
else
if
(
java_lang_invoke_MethodType
::
is_instance
(
o
))
return
new
(
arena
())
ciMethodType
(
h_i
);
else
return
new
(
arena
())
ciInstance
(
h_i
);
}
else
if
(
o
->
is_objArray
())
{
...
...
hotspot/src/share/vm/ci/ciSignature.cpp
浏览文件 @
75733dd8
...
...
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
#include "ci/ciMethodType.hpp"
#include "ci/ciSignature.hpp"
#include "ci/ciUtilities.hpp"
#include "memory/allocation.inline.hpp"
...
...
@@ -79,6 +80,24 @@ ciSignature::ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciS
_count
=
count
;
}
// ------------------------------------------------------------------
// ciSignature::ciSignature
ciSignature
::
ciSignature
(
ciKlass
*
accessing_klass
,
ciSymbol
*
symbol
,
ciMethodType
*
method_type
)
:
_symbol
(
symbol
),
_accessing_klass
(
accessing_klass
),
_size
(
method_type
->
ptype_slot_count
()),
_count
(
method_type
->
ptype_count
())
{
ASSERT_IN_VM
;
EXCEPTION_CONTEXT
;
Arena
*
arena
=
CURRENT_ENV
->
arena
();
_types
=
new
(
arena
)
GrowableArray
<
ciType
*>
(
arena
,
_count
+
1
,
0
,
NULL
);
for
(
int
i
=
0
;
i
<
_count
;
i
++
)
{
_types
->
append
(
method_type
->
ptype_at
(
i
));
}
_types
->
append
(
method_type
->
rtype
());
}
// ------------------------------------------------------------------
// ciSignature::return_type
//
...
...
hotspot/src/share/vm/ci/ciSignature.hpp
浏览文件 @
75733dd8
...
...
@@ -47,6 +47,7 @@ private:
friend
class
ciObjectFactory
;
ciSignature
(
ciKlass
*
accessing_klass
,
constantPoolHandle
cpool
,
ciSymbol
*
signature
);
ciSignature
(
ciKlass
*
accessing_klass
,
ciSymbol
*
signature
,
ciMethodType
*
method_type
);
void
get_all_klasses
();
...
...
hotspot/src/share/vm/ci/ciStreams.cpp
浏览文件 @
75733dd8
...
...
@@ -364,12 +364,15 @@ ciMethod* ciBytecodeStream::get_method(bool& will_link, ciSignature* *declared_s
constantPoolHandle
cpool
(
_method
->
get_Method
()
->
constants
());
ciMethod
*
m
=
env
->
get_method_by_index
(
cpool
,
get_method_index
(),
cur_bc
(),
_holder
);
will_link
=
m
->
is_loaded
();
// Get declared method signature and return it.
if
(
has_optional_appendix
())
{
const
int
sig_index
=
get_method_signature_index
();
Symbol
*
sig_sym
=
cpool
->
symbol_at
(
sig_index
);
ciKlass
*
pool_holder
=
env
->
get_klass
(
cpool
->
pool_holder
());
(
*
declared_signature_result
)
=
new
(
env
->
arena
())
ciSignature
(
pool_holder
,
cpool
,
env
->
get_symbol
(
sig_sym
));
// Use the MethodType stored in the CP cache to create a signature
// with correct types (in respect to class loaders).
if
(
has_method_type
())
{
ciSymbol
*
sig_sym
=
env
->
get_symbol
(
cpool
->
symbol_at
(
get_method_signature_index
()));
ciKlass
*
pool_holder
=
env
->
get_klass
(
cpool
->
pool_holder
());
ciMethodType
*
method_type
=
get_method_type
();
ciSignature
*
declared_signature
=
new
(
env
->
arena
())
ciSignature
(
pool_holder
,
sig_sym
,
method_type
);
(
*
declared_signature_result
)
=
declared_signature
;
}
else
{
(
*
declared_signature_result
)
=
m
->
signature
();
}
...
...
@@ -399,6 +402,31 @@ ciObject* ciBytecodeStream::get_appendix() {
return
CURRENT_ENV
->
get_object
(
appendix_oop
);
}
// ------------------------------------------------------------------
// ciBytecodeStream::has_method_type
//
// Returns true if there is a MethodType argument stored in the
// constant pool cache at the current bci.
bool
ciBytecodeStream
::
has_method_type
()
{
GUARDED_VM_ENTRY
(
constantPoolHandle
cpool
(
_method
->
get_Method
()
->
constants
());
return
ConstantPool
::
has_method_type_at_if_loaded
(
cpool
,
get_method_index
());
)
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_method_type
//
// Return the MethodType stored in the constant pool cache at
// the current bci.
ciMethodType
*
ciBytecodeStream
::
get_method_type
()
{
GUARDED_VM_ENTRY
(
constantPoolHandle
cpool
(
_method
->
get_Method
()
->
constants
());
oop
method_type_oop
=
ConstantPool
::
method_type_at_if_loaded
(
cpool
,
get_method_index
());
return
CURRENT_ENV
->
get_object
(
method_type_oop
)
->
as_method_type
();
)
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_declared_method_holder
//
...
...
hotspot/src/share/vm/ci/ciStreams.hpp
浏览文件 @
75733dd8
...
...
@@ -257,12 +257,14 @@ public:
int
get_field_holder_index
();
int
get_field_signature_index
();
ciMethod
*
get_method
(
bool
&
will_link
,
ciSignature
*
*
declared_signature_result
);
bool
has_appendix
();
ciObject
*
get_appendix
();
ciKlass
*
get_declared_method_holder
();
int
get_method_holder_index
();
int
get_method_signature_index
();
ciMethod
*
get_method
(
bool
&
will_link
,
ciSignature
*
*
declared_signature_result
);
bool
has_appendix
();
ciObject
*
get_appendix
();
bool
has_method_type
();
ciMethodType
*
get_method_type
();
ciKlass
*
get_declared_method_holder
();
int
get_method_holder_index
();
int
get_method_signature_index
();
// Get the resolved references arrays from the constant pool
ciObjArray
*
get_resolved_references
();
...
...
hotspot/src/share/vm/classfile/systemDictionary.cpp
浏览文件 @
75733dd8
...
...
@@ -2429,7 +2429,8 @@ static methodHandle unpack_method_and_appendix(Handle mname,
methodHandle
SystemDictionary
::
find_method_handle_invoker
(
Symbol
*
name
,
Symbol
*
signature
,
KlassHandle
accessing_klass
,
Handle
*
appendix_result
,
Handle
*
appendix_result
,
Handle
*
method_type_result
,
TRAPS
)
{
methodHandle
empty
;
assert
(
EnableInvokeDynamic
,
""
);
...
...
@@ -2461,6 +2462,7 @@ methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name,
vmSymbols
::
linkMethod_signature
(),
&
args
,
CHECK_
(
empty
));
Handle
mname
(
THREAD
,
(
oop
)
result
.
get_jobject
());
(
*
method_type_result
)
=
method_type
;
return
unpack_method_and_appendix
(
mname
,
appendix_box
,
appendix_result
,
THREAD
);
}
...
...
@@ -2607,7 +2609,8 @@ methodHandle SystemDictionary::find_dynamic_call_site_invoker(KlassHandle caller
Handle
bootstrap_specifier
,
Symbol
*
name
,
Symbol
*
type
,
Handle
*
appendix_result
,
Handle
*
appendix_result
,
Handle
*
method_type_result
,
TRAPS
)
{
methodHandle
empty
;
Handle
bsm
,
info
;
...
...
@@ -2650,6 +2653,7 @@ methodHandle SystemDictionary::find_dynamic_call_site_invoker(KlassHandle caller
vmSymbols
::
linkCallSite_signature
(),
&
args
,
CHECK_
(
empty
));
Handle
mname
(
THREAD
,
(
oop
)
result
.
get_jobject
());
(
*
method_type_result
)
=
method_type
;
return
unpack_method_and_appendix
(
mname
,
appendix_box
,
appendix_result
,
THREAD
);
}
...
...
hotspot/src/share/vm/classfile/systemDictionary.hpp
浏览文件 @
75733dd8
...
...
@@ -497,6 +497,7 @@ public:
Symbol
*
signature
,
KlassHandle
accessing_klass
,
Handle
*
appendix_result
,
Handle
*
method_type_result
,
TRAPS
);
// for a given signature, find the internal MethodHandle method (linkTo* or invokeBasic)
// (does not ask Java, since this is a low-level intrinsic defined by the JVM)
...
...
@@ -523,6 +524,7 @@ public:
Symbol
*
name
,
Symbol
*
type
,
Handle
*
appendix_result
,
Handle
*
method_type_result
,
TRAPS
);
// Utility for printing loader "name" as part of tracing constraints
...
...
hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
浏览文件 @
75733dd8
...
...
@@ -737,6 +737,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invokehandle(JavaThread* thread)) {
pool
,
info
.
resolved_method
(),
info
.
resolved_appendix
(),
info
.
resolved_method_type
(),
pool
->
resolved_references
());
}
IRT_END
...
...
@@ -765,6 +766,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
pool
,
info
.
resolved_method
(),
info
.
resolved_appendix
(),
info
.
resolved_method_type
(),
pool
->
resolved_references
());
}
IRT_END
...
...
hotspot/src/share/vm/interpreter/linkResolver.cpp
浏览文件 @
75733dd8
...
...
@@ -99,7 +99,7 @@ void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klas
assert
(
!
resolved_method
->
is_compiled_lambda_form
(),
"these must be handled via an invokehandle call"
);
}
void
CallInfo
::
set_handle
(
methodHandle
resolved_method
,
Handle
resolved_appendix
,
TRAPS
)
{
void
CallInfo
::
set_handle
(
methodHandle
resolved_method
,
Handle
resolved_appendix
,
Handle
resolved_method_type
,
TRAPS
)
{
if
(
resolved_method
.
is_null
())
{
THROW_MSG
(
vmSymbols
::
java_lang_InternalError
(),
"resolved method is null"
);
}
...
...
@@ -110,7 +110,8 @@ void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix
int
vtable_index
=
Method
::
nonvirtual_vtable_index
;
assert
(
resolved_method
->
vtable_index
()
==
vtable_index
,
""
);
set_common
(
resolved_klass
,
resolved_klass
,
resolved_method
,
resolved_method
,
vtable_index
,
CHECK
);
_resolved_appendix
=
resolved_appendix
;
_resolved_appendix
=
resolved_appendix
;
_resolved_method_type
=
resolved_method_type
;
}
void
CallInfo
::
set_common
(
KlassHandle
resolved_klass
,
KlassHandle
selected_klass
,
methodHandle
resolved_method
,
methodHandle
selected_method
,
int
vtable_index
,
TRAPS
)
{
...
...
@@ -221,7 +222,8 @@ void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle
void
LinkResolver
::
lookup_polymorphic_method
(
methodHandle
&
result
,
KlassHandle
klass
,
Symbol
*
name
,
Symbol
*
full_signature
,
KlassHandle
current_klass
,
Handle
*
appendix_result_or_null
,
Handle
*
appendix_result_or_null
,
Handle
*
method_type_result
,
TRAPS
)
{
vmIntrinsics
::
ID
iid
=
MethodHandles
::
signature_polymorphic_name_id
(
name
);
if
(
TraceMethodHandles
)
{
...
...
@@ -275,10 +277,12 @@ void LinkResolver::lookup_polymorphic_method(methodHandle& result,
}
Handle
appendix
;
Handle
method_type
;
result
=
SystemDictionary
::
find_method_handle_invoker
(
name
,
full_signature
,
current_klass
,
&
appendix
,
&
method_type
,
CHECK
);
if
(
TraceMethodHandles
)
{
tty
->
print
(
"lookup_polymorphic_method => (via Java) "
);
...
...
@@ -307,6 +311,7 @@ void LinkResolver::lookup_polymorphic_method(methodHandle& result,
assert
(
appendix_result_or_null
!=
NULL
,
""
);
(
*
appendix_result_or_null
)
=
appendix
;
(
*
method_type_result
)
=
method_type
;
return
;
}
}
...
...
@@ -419,7 +424,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
if
(
resolved_method
.
is_null
())
{
// JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
lookup_polymorphic_method
(
resolved_method
,
resolved_klass
,
method_name
,
method_signature
,
current_klass
,
(
Handle
*
)
NULL
,
THREAD
);
current_klass
,
(
Handle
*
)
NULL
,
(
Handle
*
)
NULL
,
THREAD
);
if
(
HAS_PENDING_EXCEPTION
)
{
nested_exception
=
Handle
(
THREAD
,
PENDING_EXCEPTION
);
CLEAR_PENDING_EXCEPTION
;
...
...
@@ -1207,11 +1212,12 @@ void LinkResolver::resolve_handle_call(CallInfo& result, KlassHandle resolved_kl
assert
(
resolved_klass
()
==
SystemDictionary
::
MethodHandle_klass
(),
""
);
assert
(
MethodHandles
::
is_signature_polymorphic_name
(
method_name
),
""
);
methodHandle
resolved_method
;
Handle
resolved_appendix
;
Handle
resolved_appendix
;
Handle
resolved_method_type
;
lookup_polymorphic_method
(
resolved_method
,
resolved_klass
,
method_name
,
method_signature
,
current_klass
,
&
resolved_appendix
,
CHECK
);
result
.
set_handle
(
resolved_method
,
resolved_appendix
,
CHECK
);
current_klass
,
&
resolved_appendix
,
&
resolved_method_type
,
CHECK
);
result
.
set_handle
(
resolved_method
,
resolved_appendix
,
resolved_method_type
,
CHECK
);
}
...
...
@@ -1219,7 +1225,7 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po
assert
(
EnableInvokeDynamic
,
""
);
pool
->
set_invokedynamic
();
// mark header to flag active call sites
//resolve_pool(<resolved_klass>, method_name,
method_signature, current_klass, pool, index, CHECK);
//resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK);
Symbol
*
method_name
=
pool
->
name_ref_at
(
index
);
Symbol
*
method_signature
=
pool
->
signature_ref_at
(
index
);
KlassHandle
current_klass
=
KlassHandle
(
THREAD
,
pool
->
pool_holder
());
...
...
@@ -1236,9 +1242,10 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po
bootstrap_specifier
=
Handle
(
THREAD
,
bsm_info
);
}
if
(
!
cpce
->
is_f1_null
())
{
methodHandle
method
(
THREAD
,
cpce
->
f1_as_method
());
Handle
appendix
(
THREAD
,
cpce
->
appendix_if_resolved
(
pool
));
result
.
set_handle
(
method
,
appendix
,
CHECK
);
methodHandle
method
(
THREAD
,
cpce
->
f1_as_method
());
Handle
appendix
(
THREAD
,
cpce
->
appendix_if_resolved
(
pool
));
Handle
method_type
(
THREAD
,
cpce
->
method_type_if_resolved
(
pool
));
result
.
set_handle
(
method
,
appendix
,
method_type
,
CHECK
);
return
;
}
...
...
@@ -1260,11 +1267,13 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
// JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...)
// The appendix argument is likely to be a freshly-created CallSite.
Handle
resolved_appendix
;
Handle
resolved_method_type
;
methodHandle
resolved_method
=
SystemDictionary
::
find_dynamic_call_site_invoker
(
current_klass
,
bootstrap_specifier
,
method_name
,
method_signature
,
&
resolved_appendix
,
&
resolved_method_type
,
THREAD
);
if
(
HAS_PENDING_EXCEPTION
)
{
if
(
TraceMethodHandles
)
{
...
...
@@ -1284,7 +1293,7 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
CLEAR_PENDING_EXCEPTION
;
THROW_CAUSE
(
vmSymbols
::
java_lang_BootstrapMethodError
(),
nested_exception
)
}
result
.
set_handle
(
resolved_method
,
resolved_appendix
,
CHECK
);
result
.
set_handle
(
resolved_method
,
resolved_appendix
,
resolved_method_type
,
CHECK
);
}
//------------------------------------------------------------------------------------------------------------------------
...
...
hotspot/src/share/vm/interpreter/linkResolver.hpp
浏览文件 @
75733dd8
...
...
@@ -76,12 +76,13 @@ class CallInfo: public LinkInfo {
methodHandle
_selected_method
;
// dynamic (actual) target method
int
_vtable_index
;
// vtable index of selected method
Handle
_resolved_appendix
;
// extra argument in constant pool (if CPCE::has_appendix)
Handle
_resolved_method_type
;
// MethodType (for invokedynamic and invokehandle call sites)
void
set_static
(
KlassHandle
resolved_klass
,
methodHandle
resolved_method
,
TRAPS
);
void
set_interface
(
KlassHandle
resolved_klass
,
KlassHandle
selected_klass
,
methodHandle
resolved_method
,
methodHandle
selected_method
,
TRAPS
);
void
set_virtual
(
KlassHandle
resolved_klass
,
KlassHandle
selected_klass
,
methodHandle
resolved_method
,
methodHandle
selected_method
,
int
vtable_index
,
TRAPS
);
void
set_handle
(
methodHandle
resolved_method
,
Handle
resolved_appendix
,
TRAPS
);
void
set_common
(
KlassHandle
resolved_klass
,
KlassHandle
selected_klass
,
methodHandle
resolved_method
,
methodHandle
selected_method
,
int
vtable_index
,
TRAPS
);
void
set_static
(
KlassHandle
resolved_klass
,
methodHandle
resolved_method
,
TRAPS
);
void
set_interface
(
KlassHandle
resolved_klass
,
KlassHandle
selected_klass
,
methodHandle
resolved_method
,
methodHandle
selected_method
,
TRAPS
);
void
set_virtual
(
KlassHandle
resolved_klass
,
KlassHandle
selected_klass
,
methodHandle
resolved_method
,
methodHandle
selected_method
,
int
vtable_index
,
TRAPS
);
void
set_handle
(
methodHandle
resolved_method
,
Handle
resolved_appendix
,
Handle
resolved_method_type
,
TRAPS
);
void
set_common
(
KlassHandle
resolved_klass
,
KlassHandle
selected_klass
,
methodHandle
resolved_method
,
methodHandle
selected_method
,
int
vtable_index
,
TRAPS
);
friend
class
LinkResolver
;
...
...
@@ -91,6 +92,7 @@ class CallInfo: public LinkInfo {
methodHandle
resolved_method
()
const
{
return
_resolved_method
;
}
methodHandle
selected_method
()
const
{
return
_selected_method
;
}
Handle
resolved_appendix
()
const
{
return
_resolved_appendix
;
}
Handle
resolved_method_type
()
const
{
return
_resolved_method_type
;
}
BasicType
result_type
()
const
{
return
selected_method
()
->
result_type
();
}
bool
has_vtable_index
()
const
{
return
_vtable_index
>=
0
;
}
...
...
@@ -113,7 +115,7 @@ class LinkResolver: AllStatic {
static
void
lookup_instance_method_in_klasses
(
methodHandle
&
result
,
KlassHandle
klass
,
Symbol
*
name
,
Symbol
*
signature
,
TRAPS
);
static
void
lookup_method_in_interfaces
(
methodHandle
&
result
,
KlassHandle
klass
,
Symbol
*
name
,
Symbol
*
signature
,
TRAPS
);
static
void
lookup_polymorphic_method
(
methodHandle
&
result
,
KlassHandle
klass
,
Symbol
*
name
,
Symbol
*
signature
,
KlassHandle
current_klass
,
Handle
*
appendix_result_or_null
,
TRAPS
);
KlassHandle
current_klass
,
Handle
*
appendix_result_or_null
,
Handle
*
method_type_result
,
TRAPS
);
static
int
vtable_index_of_miranda_method
(
KlassHandle
klass
,
Symbol
*
name
,
Symbol
*
signature
,
TRAPS
);
...
...
hotspot/src/share/vm/interpreter/rewriter.cpp
浏览文件 @
75733dd8
...
...
@@ -179,7 +179,7 @@ void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_i
MethodHandles
::
is_signature_polymorphic_name
(
SystemDictionary
::
MethodHandle_klass
(),
_pool
->
name_ref_at
(
cp_index
)))
{
// we may need a resolved_refs entry for the appendix
add_invokedynamic_resolved_references_entr
y
(
cp_index
,
cache_index
);
add_invokedynamic_resolved_references_entr
ies
(
cp_index
,
cache_index
);
status
=
+
1
;
}
else
{
status
=
-
1
;
...
...
@@ -211,7 +211,7 @@ void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) {
if
(
!
reverse
)
{
int
cp_index
=
Bytes
::
get_Java_u2
(
p
);
int
cache_index
=
add_invokedynamic_cp_cache_entry
(
cp_index
);
add_invokedynamic_resolved_references_entr
y
(
cp_index
,
cache_index
);
add_invokedynamic_resolved_references_entr
ies
(
cp_index
,
cache_index
);
// Replace the trailing four bytes with a CPC index for the dynamic
// call site. Unlike other CPC entries, there is one per bytecode,
// not just one per distinct CP entry. In other words, the
...
...
hotspot/src/share/vm/interpreter/rewriter.hpp
浏览文件 @
75733dd8
...
...
@@ -113,12 +113,19 @@ class Rewriter: public StackObj {
return
ref_index
;
}
// add a new entr
y to the resolved_references map (for invokedynamic
only)
int
add_invokedynamic_resolved_references_entr
y
(
int
cp_index
,
int
cache_index
)
{
// add a new entr
ies to the resolved_references map (for invokedynamic and invokehandle
only)
int
add_invokedynamic_resolved_references_entr
ies
(
int
cp_index
,
int
cache_index
)
{
assert
(
_resolved_reference_limit
>=
0
,
"must add indy refs after first iteration"
);
int
ref_index
=
_resolved_references_map
.
append
(
cp_index
);
// many-to-one
assert
(
ref_index
>=
_resolved_reference_limit
,
""
);
_invokedynamic_references_map
.
at_put_grow
(
ref_index
,
cache_index
,
-
1
);
int
ref_index
=
-
1
;
for
(
int
entry
=
0
;
entry
<
ConstantPoolCacheEntry
::
_indy_resolved_references_entries
;
entry
++
)
{
const
int
index
=
_resolved_references_map
.
append
(
cp_index
);
// many-to-one
assert
(
index
>=
_resolved_reference_limit
,
""
);
if
(
entry
==
0
)
{
ref_index
=
index
;
}
assert
((
index
-
entry
)
==
ref_index
,
"entries must be consecutive"
);
_invokedynamic_references_map
.
at_put_grow
(
index
,
cache_index
,
-
1
);
}
return
ref_index
;
}
...
...
@@ -127,15 +134,6 @@ class Rewriter: public StackObj {
return
cp_index
;
}
// invokedynamic support - append the cpCache entry (encoded) in object map.
// The resolved_references_map should still be in ascending order
// The resolved_references has the invokedynamic call site objects appended after
// the objects that are resolved in the constant pool.
int
add_callsite_entry
(
int
main_cpc_entry
)
{
int
ref_index
=
_resolved_references_map
.
append
(
main_cpc_entry
);
return
ref_index
;
}
// Access the contents of _cp_cache_map to determine CP cache layout.
int
cp_cache_entry_pool_index
(
int
cache_index
)
{
int
cp_index
=
_cp_cache_map
[
cache_index
];
...
...
hotspot/src/share/vm/oops/constantPool.cpp
浏览文件 @
75733dd8
...
...
@@ -445,7 +445,6 @@ bool ConstantPool::has_appendix_at_if_loaded(constantPoolHandle cpool, int which
return
e
->
has_appendix
();
}
oop
ConstantPool
::
appendix_at_if_loaded
(
constantPoolHandle
cpool
,
int
which
)
{
if
(
cpool
->
cache
()
==
NULL
)
return
NULL
;
// nothing to load yet
int
cache_index
=
decode_cpcache_index
(
which
,
true
);
...
...
@@ -454,6 +453,21 @@ oop ConstantPool::appendix_at_if_loaded(constantPoolHandle cpool, int which) {
}
bool
ConstantPool
::
has_method_type_at_if_loaded
(
constantPoolHandle
cpool
,
int
which
)
{
if
(
cpool
->
cache
()
==
NULL
)
return
false
;
// nothing to load yet
int
cache_index
=
decode_cpcache_index
(
which
,
true
);
ConstantPoolCacheEntry
*
e
=
cpool
->
cache
()
->
entry_at
(
cache_index
);
return
e
->
has_method_type
();
}
oop
ConstantPool
::
method_type_at_if_loaded
(
constantPoolHandle
cpool
,
int
which
)
{
if
(
cpool
->
cache
()
==
NULL
)
return
NULL
;
// nothing to load yet
int
cache_index
=
decode_cpcache_index
(
which
,
true
);
ConstantPoolCacheEntry
*
e
=
cpool
->
cache
()
->
entry_at
(
cache_index
);
return
e
->
method_type_if_resolved
(
cpool
);
}
Symbol
*
ConstantPool
::
impl_name_ref_at
(
int
which
,
bool
uncached
)
{
int
name_index
=
name_ref_index_at
(
impl_name_and_type_ref_index_at
(
which
,
uncached
));
return
symbol_at
(
name_index
);
...
...
hotspot/src/share/vm/oops/constantPool.hpp
浏览文件 @
75733dd8
...
...
@@ -694,13 +694,15 @@ class ConstantPool : public Metadata {
friend
class
SystemDictionary
;
// Used by compiler to prevent classloading.
static
Method
*
method_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
bool
has_appendix_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
oop
appendix_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
Klass
*
klass_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
Klass
*
klass_ref_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
Method
*
method_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
bool
has_appendix_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
oop
appendix_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
bool
has_method_type_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
oop
method_type_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
Klass
*
klass_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
static
Klass
*
klass_ref_at_if_loaded
(
constantPoolHandle
this_oop
,
int
which
);
// Same as above - but does LinkResolving.
static
Klass
*
klass_ref_at_if_loaded_check
(
constantPoolHandle
this_oop
,
int
which
,
TRAPS
);
static
Klass
*
klass_ref_at_if_loaded_check
(
constantPoolHandle
this_oop
,
int
which
,
TRAPS
);
// Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
// future by other Java code. These take constant pool indices rather than
...
...
hotspot/src/share/vm/oops/cpCache.cpp
浏览文件 @
75733dd8
...
...
@@ -244,21 +244,23 @@ void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index)
void
ConstantPoolCacheEntry
::
set_method_handle
(
constantPoolHandle
cpool
,
methodHandle
adapter
,
Handle
appendix
,
methodHandle
adapter
,
Handle
appendix
,
Handle
method_type
,
objArrayHandle
resolved_references
)
{
set_method_handle_common
(
cpool
,
Bytecodes
::
_invokehandle
,
adapter
,
appendix
,
resolved_references
);
set_method_handle_common
(
cpool
,
Bytecodes
::
_invokehandle
,
adapter
,
appendix
,
method_type
,
resolved_references
);
}
void
ConstantPoolCacheEntry
::
set_dynamic_call
(
constantPoolHandle
cpool
,
methodHandle
adapter
,
Handle
appendix
,
methodHandle
adapter
,
Handle
appendix
,
Handle
method_type
,
objArrayHandle
resolved_references
)
{
set_method_handle_common
(
cpool
,
Bytecodes
::
_invokedynamic
,
adapter
,
appendix
,
resolved_references
);
set_method_handle_common
(
cpool
,
Bytecodes
::
_invokedynamic
,
adapter
,
appendix
,
method_type
,
resolved_references
);
}
void
ConstantPoolCacheEntry
::
set_method_handle_common
(
constantPoolHandle
cpool
,
Bytecodes
::
Code
invoke_code
,
methodHandle
adapter
,
Handle
appendix
,
Handle
appendix
,
Handle
method_type
,
objArrayHandle
resolved_references
)
{
// NOTE: This CPCE can be the subject of data races.
// There are three words to update: flags, refs[f2], f1 (in that order).
...
...
@@ -274,18 +276,21 @@ void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
return
;
}
bool
has_appendix
=
appendix
.
not_null
();
const
bool
has_appendix
=
appendix
.
not_null
();
const
bool
has_method_type
=
method_type
.
not_null
();
// Write the flags.
set_method_flags
(
as_TosState
(
adapter
->
result_type
()),
((
has_appendix
?
1
:
0
)
<<
has_appendix_shift
)
|
(
1
<<
is_final_shift
),
((
has_appendix
?
1
:
0
)
<<
has_appendix_shift
)
|
((
has_method_type
?
1
:
0
)
<<
has_method_type_shift
)
|
(
1
<<
is_final_shift
),
adapter
->
size_of_parameters
());
if
(
TraceInvokeDynamic
)
{
tty
->
print_cr
(
"set_method_handle bc=%d appendix="
PTR_FORMAT
"%s method="
PTR_FORMAT
" "
,
tty
->
print_cr
(
"set_method_handle bc=%d appendix="
PTR_FORMAT
"%s method
_type="
PTR_FORMAT
"%s method
="
PTR_FORMAT
" "
,
invoke_code
,
(
intptr_t
)
appendix
(),
(
has_appendix
?
""
:
" (unused)"
),
(
intptr_t
)
appendix
(),
(
has_appendix
?
""
:
" (unused)"
),
(
intptr_t
)
method_type
(),
(
has_method_type
?
""
:
" (unused)"
),
(
intptr_t
)
adapter
());
adapter
->
print
();
if
(
has_appendix
)
appendix
()
->
print
();
...
...
@@ -310,17 +315,26 @@ void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
// This allows us to create fewer method oops, while keeping type safety.
//
// Store appendix, if any.
if
(
has_appendix
)
{
int
ref_index
=
f2_as_index
();
assert
(
ref_index
>=
0
&&
ref_index
<
resolved_references
->
length
(),
"oob"
);
assert
(
resolved_references
->
obj_at
(
ref_index
)
==
NULL
,
"init just once"
);
resolved_references
->
obj_at_put
(
ref_index
,
appendix
());
const
int
appendix_index
=
f2_as_index
()
+
_indy_resolved_references_appendix_offset
;
assert
(
appendix_index
>=
0
&&
appendix_index
<
resolved_references
->
length
(),
"oob"
);
assert
(
resolved_references
->
obj_at
(
appendix_index
)
==
NULL
,
"init just once"
);
resolved_references
->
obj_at_put
(
appendix_index
,
appendix
());
}
// Store MethodType, if any.
if
(
has_method_type
)
{
const
int
method_type_index
=
f2_as_index
()
+
_indy_resolved_references_method_type_offset
;
assert
(
method_type_index
>=
0
&&
method_type_index
<
resolved_references
->
length
(),
"oob"
);
assert
(
resolved_references
->
obj_at
(
method_type_index
)
==
NULL
,
"init just once"
);
resolved_references
->
obj_at_put
(
method_type_index
,
method_type
());
}
release_set_f1
(
adapter
());
// This must be the last one to set (see NOTE above)!
// The interpreter assembly code does not check byte_2,
// but it is used by is_resolved, method_if_resolved, etc.
// The interpreter assembly code does not check byte_2,
// but it is used by is_resolved, method_if_resolved, etc.
set_bytecode_1
(
invoke_code
);
NOT_PRODUCT
(
verify
(
tty
));
if
(
TraceInvokeDynamic
)
{
...
...
@@ -376,7 +390,16 @@ Method* ConstantPoolCacheEntry::method_if_resolved(constantPoolHandle cpool) {
oop
ConstantPoolCacheEntry
::
appendix_if_resolved
(
constantPoolHandle
cpool
)
{
if
(
is_f1_null
()
||
!
has_appendix
())
return
NULL
;
int
ref_index
=
f2_as_index
();
const
int
ref_index
=
f2_as_index
()
+
_indy_resolved_references_appendix_offset
;
objArrayOop
resolved_references
=
cpool
->
resolved_references
();
return
resolved_references
->
obj_at
(
ref_index
);
}
oop
ConstantPoolCacheEntry
::
method_type_if_resolved
(
constantPoolHandle
cpool
)
{
if
(
is_f1_null
()
||
!
has_method_type
())
return
NULL
;
const
int
ref_index
=
f2_as_index
()
+
_indy_resolved_references_method_type_offset
;
objArrayOop
resolved_references
=
cpool
->
resolved_references
();
return
resolved_references
->
obj_at
(
ref_index
);
}
...
...
@@ -513,13 +536,23 @@ void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invoke
for
(
int
i
=
0
;
i
<
length
();
i
++
)
{
ConstantPoolCacheEntry
*
e
=
entry_at
(
i
);
int
original_index
=
inverse_index_map
[
i
];
e
->
initialize_entry
(
original_index
);
e
->
initialize_entry
(
original_index
);
assert
(
entry_at
(
i
)
==
e
,
"sanity"
);
}
}
for
(
int
ref
=
0
;
ref
<
invokedynamic_references_map
.
length
();
ref
++
)
{
int
cpci
=
invokedynamic_references_map
[
ref
];
if
(
cpci
>=
0
)
const
int
cpci
=
invokedynamic_references_map
[
ref
];
if
(
cpci
>=
0
)
{
#ifdef ASSERT
// invokedynamic and invokehandle have more entries; check if they
// all point to the same constant pool cache entry.
for
(
int
entry
=
1
;
entry
<
ConstantPoolCacheEntry
::
_indy_resolved_references_entries
;
entry
++
)
{
const
int
cpci_next
=
invokedynamic_references_map
[
ref
+
entry
];
assert
(
cpci
==
cpci_next
,
err_msg_res
(
"%d == %d"
,
cpci
,
cpci_next
));
}
#endif
entry_at
(
cpci
)
->
initialize_resolved_reference_index
(
ref
);
ref
+=
ConstantPoolCacheEntry
::
_indy_resolved_references_entries
-
1
;
// skip extra entries
}
}
}
...
...
hotspot/src/share/vm/oops/cpCache.hpp
浏览文件 @
75733dd8
...
...
@@ -42,10 +42,10 @@ class PSPromotionManager;
// _indices [ b2 | b1 | index ] index = constant_pool_index
// _f1 [ entry specific ] metadata ptr (method or klass)
// _f2 [ entry specific ] vtable or res_ref index, or vfinal method ptr
// _flags [tos|0|F=1|0|0|
f|v|0 |0
0000|field_index] (for field entries)
// bit length [ 4 |1| 1 |1|1|1|1|1
|--5
--|----16-----]
// _flags [tos|0|F=0|
A|I|f|0|vf|0
0000|00000|psize] (for method entries)
// bit length [ 4 |1| 1 |1|1|1|1|1
|--5
--|--8--|--8--]
// _flags [tos|0|F=1|0|0|
0|f|v|0 |
0000|field_index] (for field entries)
// bit length [ 4 |1| 1 |1|1|1|1|1
|1 |-4
--|----16-----]
// _flags [tos|0|F=0|
M|A|I|f|0|vf|
0000|00000|psize] (for method entries)
// bit length [ 4 |1| 1 |1|1|1|1|1
|1 |-4
--|--8--|--8--]
// --------------------------------
//
...
...
@@ -166,11 +166,12 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
tos_state_shift
=
BitsPerInt
-
tos_state_bits
,
// see verify_tos_state_shift below
// misc. option bits; can be any bit position in [16..27]
is_field_entry_shift
=
26
,
// (F) is it a field or a method?
has_appendix_shift
=
25
,
// (A) does the call site have an appendix argument?
is_forced_virtual_shift
=
24
,
// (I) is the interface reference forced to virtual mode?
is_final_shift
=
23
,
// (f) is the field or method final?
is_volatile_shift
=
22
,
// (v) is the field volatile?
is_vfinal_shift
=
21
,
// (vf) did the call resolve to a final method?
has_method_type_shift
=
25
,
// (M) does the call site have a MethodType?
has_appendix_shift
=
24
,
// (A) does the call site have an appendix argument?
is_forced_virtual_shift
=
23
,
// (I) is the interface reference forced to virtual mode?
is_final_shift
=
22
,
// (f) is the field or method final?
is_volatile_shift
=
21
,
// (v) is the field volatile?
is_vfinal_shift
=
20
,
// (vf) did the call resolve to a final method?
// low order bits give field index (for FieldInfo) or method parameter size:
field_index_bits
=
16
,
field_index_mask
=
right_n_bits
(
field_index_bits
),
...
...
@@ -223,14 +224,16 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
void
set_method_handle
(
constantPoolHandle
cpool
,
// holding constant pool (required for locking)
methodHandle
method
,
// adapter for invokeExact, etc.
Handle
appendix
,
// stored in refs[f2]; could be a java.lang.invoke.MethodType
Handle
appendix
,
// stored in refs[f2+0]; could be a java.lang.invoke.MethodType
Handle
method_type
,
// stored in refs[f2+1]; is a java.lang.invoke.MethodType
objArrayHandle
resolved_references
);
void
set_dynamic_call
(
constantPoolHandle
cpool
,
// holding constant pool (required for locking)
methodHandle
method
,
// adapter for this call site
Handle
appendix
,
// stored in refs[f2]; could be a java.lang.invoke.CallSite
Handle
appendix
,
// stored in refs[f2+0]; could be a java.lang.invoke.CallSite
Handle
method_type
,
// stored in refs[f2+1]; is a java.lang.invoke.MethodType
objArrayHandle
resolved_references
);
...
...
@@ -253,12 +256,24 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
constantPoolHandle
cpool
,
// holding constant pool (required for locking)
Bytecodes
::
Code
invoke_code
,
// _invokehandle or _invokedynamic
methodHandle
adapter
,
// invoker method (f1)
Handle
appendix
,
// appendix such as CallSite, MethodType, etc. (refs[f2])
Handle
appendix
,
// appendix such as CallSite, MethodType, etc. (refs[f2+0])
Handle
method_type
,
// MethodType (refs[f2+1])
objArrayHandle
resolved_references
);
Method
*
method_if_resolved
(
constantPoolHandle
cpool
);
oop
appendix_if_resolved
(
constantPoolHandle
cpool
);
// invokedynamic and invokehandle call sites have two entries in the
// resolved references array:
// appendix (at index+0)
// MethodType (at index+1)
enum
{
_indy_resolved_references_appendix_offset
=
0
,
_indy_resolved_references_method_type_offset
=
1
,
_indy_resolved_references_entries
};
Method
*
method_if_resolved
(
constantPoolHandle
cpool
);
oop
appendix_if_resolved
(
constantPoolHandle
cpool
);
oop
method_type_if_resolved
(
constantPoolHandle
cpool
);
void
set_parameter_size
(
int
value
);
...
...
@@ -270,11 +285,11 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
case
Bytecodes
::
_getfield
:
// fall through
case
Bytecodes
::
_invokespecial
:
// fall through
case
Bytecodes
::
_invokestatic
:
// fall through
case
Bytecodes
::
_invokehandle
:
// fall through
case
Bytecodes
::
_invokedynamic
:
// fall through
case
Bytecodes
::
_invokeinterface
:
return
1
;
case
Bytecodes
::
_putstatic
:
// fall through
case
Bytecodes
::
_putfield
:
// fall through
case
Bytecodes
::
_invokehandle
:
// fall through
case
Bytecodes
::
_invokedynamic
:
// fall through
case
Bytecodes
::
_invokevirtual
:
return
2
;
default
:
break
;
}
...
...
@@ -307,6 +322,7 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
bool
is_forced_virtual
()
const
{
return
(
_flags
&
(
1
<<
is_forced_virtual_shift
))
!=
0
;
}
bool
is_vfinal
()
const
{
return
(
_flags
&
(
1
<<
is_vfinal_shift
))
!=
0
;
}
bool
has_appendix
()
const
{
return
(
_flags
&
(
1
<<
has_appendix_shift
))
!=
0
;
}
bool
has_method_type
()
const
{
return
(
_flags
&
(
1
<<
has_method_type_shift
))
!=
0
;
}
bool
is_method_entry
()
const
{
return
(
_flags
&
(
1
<<
is_field_entry_shift
))
==
0
;
}
bool
is_field_entry
()
const
{
return
(
_flags
&
(
1
<<
is_field_entry_shift
))
!=
0
;
}
bool
is_byte
()
const
{
return
flag_state
()
==
btos
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录