Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
59f3dfa2
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看板
提交
59f3dfa2
编写于
5月 17, 2011
作者:
N
never
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
Reviewed-by: jrose
上级
66a7efff
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
332 addition
and
62 deletion
+332
-62
agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
...t/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
+6
-1
agent/src/share/classes/sun/jvm/hotspot/code/AdapterBlob.java
...t/src/share/classes/sun/jvm/hotspot/code/AdapterBlob.java
+58
-0
agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java
agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java
+3
-1
agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
+3
-1
agent/src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java
.../src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java
+56
-0
src/cpu/x86/vm/methodHandles_x86.cpp
src/cpu/x86/vm/methodHandles_x86.cpp
+1
-1
src/share/vm/ci/ciMethodHandle.cpp
src/share/vm/ci/ciMethodHandle.cpp
+1
-1
src/share/vm/interpreter/bytecodeTracer.cpp
src/share/vm/interpreter/bytecodeTracer.cpp
+8
-5
src/share/vm/opto/idealGraphPrinter.cpp
src/share/vm/opto/idealGraphPrinter.cpp
+2
-0
src/share/vm/prims/methodHandleWalk.cpp
src/share/vm/prims/methodHandleWalk.cpp
+108
-30
src/share/vm/prims/methodHandleWalk.hpp
src/share/vm/prims/methodHandleWalk.hpp
+23
-16
src/share/vm/prims/methodHandles.cpp
src/share/vm/prims/methodHandles.cpp
+52
-4
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/globals.hpp
+3
-0
src/share/vm/runtime/thread.cpp
src/share/vm/runtime/thread.cpp
+2
-1
src/share/vm/runtime/vmStructs.cpp
src/share/vm/runtime/vmStructs.cpp
+6
-1
未找到文件。
agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
浏览文件 @
59f3dfa2
...
...
@@ -1028,7 +1028,12 @@ public class CommandProcessor {
if
(
AddressOps
.
equal
(
val
,
value
))
{
if
(!
printed
)
{
printed
=
true
;
blob
.
printOn
(
out
);
try
{
blob
.
printOn
(
out
);
}
catch
(
Exception
e
)
{
out
.
println
(
"Exception printing blob at "
+
base
);
e
.
printStackTrace
();
}
}
out
.
println
(
"found at "
+
base
+
"\n"
);
}
...
...
agent/src/share/classes/sun/jvm/hotspot/code/AdapterBlob.java
0 → 100644
浏览文件 @
59f3dfa2
/*
* Copyright (c) 2011, 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.
*
*/
package
sun.jvm.hotspot.code
;
import
java.util.*
;
import
sun.jvm.hotspot.debugger.*
;
import
sun.jvm.hotspot.runtime.*
;
import
sun.jvm.hotspot.types.*
;
public
class
AdapterBlob
extends
CodeBlob
{
static
{
VM
.
registerVMInitializedObserver
(
new
Observer
()
{
public
void
update
(
Observable
o
,
Object
data
)
{
initialize
(
VM
.
getVM
().
getTypeDataBase
());
}
});
}
private
static
void
initialize
(
TypeDataBase
db
)
{
// Type type = db.lookupType("AdapterBlob");
// // FIXME: add any needed fields
}
public
AdapterBlob
(
Address
addr
)
{
super
(
addr
);
}
public
boolean
isAdapterBlob
()
{
return
true
;
}
public
String
getName
()
{
return
"AdapterBlob: "
+
super
.
getName
();
}
}
agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java
浏览文件 @
59f3dfa2
/*
* Copyright (c) 2000, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
1
, 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
...
...
@@ -93,6 +93,8 @@ public class CodeBlob extends VMObject {
public
boolean
isUncommonTrapStub
()
{
return
false
;
}
public
boolean
isExceptionStub
()
{
return
false
;
}
public
boolean
isSafepointStub
()
{
return
false
;
}
public
boolean
isRicochetBlob
()
{
return
false
;
}
public
boolean
isAdapterBlob
()
{
return
false
;
}
// Fine grain nmethod support: isNmethod() == isJavaMethod() || isNativeMethod() || isOSRMethod()
public
boolean
isJavaMethod
()
{
return
false
;
}
...
...
agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
浏览文件 @
59f3dfa2
/*
* Copyright (c) 2000, 20
05
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 20
11
, 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,8 @@ public class CodeCache {
virtualConstructor
.
addMapping
(
"BufferBlob"
,
BufferBlob
.
class
);
virtualConstructor
.
addMapping
(
"nmethod"
,
NMethod
.
class
);
virtualConstructor
.
addMapping
(
"RuntimeStub"
,
RuntimeStub
.
class
);
virtualConstructor
.
addMapping
(
"RicochetBlob"
,
RicochetBlob
.
class
);
virtualConstructor
.
addMapping
(
"AdapterBlob"
,
AdapterBlob
.
class
);
virtualConstructor
.
addMapping
(
"SafepointBlob"
,
SafepointBlob
.
class
);
virtualConstructor
.
addMapping
(
"DeoptimizationBlob"
,
DeoptimizationBlob
.
class
);
if
(
VM
.
getVM
().
isServerCompiler
())
{
...
...
agent/src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java
0 → 100644
浏览文件 @
59f3dfa2
/*
* Copyright (c) 2011, 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.
*
*/
package
sun.jvm.hotspot.code
;
import
java.util.*
;
import
sun.jvm.hotspot.debugger.*
;
import
sun.jvm.hotspot.runtime.*
;
import
sun.jvm.hotspot.types.*
;
/** RicochetBlob (currently only used by Compiler 2) */
public
class
RicochetBlob
extends
SingletonBlob
{
static
{
VM
.
registerVMInitializedObserver
(
new
Observer
()
{
public
void
update
(
Observable
o
,
Object
data
)
{
initialize
(
VM
.
getVM
().
getTypeDataBase
());
}
});
}
private
static
void
initialize
(
TypeDataBase
db
)
{
// Type type = db.lookupType("RicochetBlob");
// FIXME: add any needed fields
}
public
RicochetBlob
(
Address
addr
)
{
super
(
addr
);
}
public
boolean
isRicochetBlob
()
{
return
true
;
}
}
src/cpu/x86/vm/methodHandles_x86.cpp
浏览文件 @
59f3dfa2
...
...
@@ -389,7 +389,7 @@ void MethodHandles::load_stack_move(MacroAssembler* _masm,
}
}
#if
ndef PRODUC
T
#if
def ASSER
T
void
MethodHandles
::
RicochetFrame
::
verify_offsets
()
{
// Check compatibility of this struct with the more generally used offsets of class frame:
int
ebp_off
=
sender_link_offset_in_bytes
();
// offset from struct base to local rbp value
...
...
src/share/vm/ci/ciMethodHandle.cpp
浏览文件 @
59f3dfa2
...
...
@@ -43,7 +43,7 @@ ciMethod* ciMethodHandle::get_adapter_impl(bool is_invokedynamic) const {
methodHandle
callee
(
_callee
->
get_methodOop
());
// We catch all exceptions here that could happen in the method
// handle compiler and stop the VM.
MethodHandleCompiler
mhc
(
h
,
callee
,
_profile
->
count
(),
is_invokedynamic
,
THREAD
);
MethodHandleCompiler
mhc
(
h
,
callee
->
name
(),
callee
->
signature
()
,
_profile
->
count
(),
is_invokedynamic
,
THREAD
);
if
(
!
HAS_PENDING_EXCEPTION
)
{
methodHandle
m
=
mhc
.
compile
(
THREAD
);
if
(
!
HAS_PENDING_EXCEPTION
)
{
...
...
src/share/vm/interpreter/bytecodeTracer.cpp
浏览文件 @
59f3dfa2
...
...
@@ -203,11 +203,14 @@ void print_oop(oop value, outputStream* st) {
if
(
value
==
NULL
)
{
st
->
print_cr
(
" NULL"
);
}
else
if
(
java_lang_String
::
is_instance
(
value
))
{
EXCEPTION_MARK
;
Handle
h_value
(
THREAD
,
value
);
Symbol
*
sym
=
java_lang_String
::
as_symbol
(
h_value
,
CATCH
);
print_symbol
(
sym
,
st
);
sym
->
decrement_refcount
();
char
buf
[
40
];
int
len
=
java_lang_String
::
utf8_length
(
value
);
java_lang_String
::
as_utf8_string
(
value
,
buf
,
sizeof
(
buf
));
if
(
len
>=
(
int
)
sizeof
(
buf
))
{
st
->
print_cr
(
" %s...[%d]"
,
buf
,
len
);
}
else
{
st
->
print_cr
(
" %s"
,
buf
);
}
}
else
{
st
->
print_cr
(
" "
PTR_FORMAT
,
(
intptr_t
)
value
);
}
...
...
src/share/vm/opto/idealGraphPrinter.cpp
浏览文件 @
59f3dfa2
...
...
@@ -615,6 +615,7 @@ void IdealGraphPrinter::visit_node(Node *n, void *param) {
}
}
#ifdef ASSERT
if
(
node
->
debug_orig
()
!=
NULL
)
{
stringStream
dorigStream
;
Node
*
dorig
=
node
->
debug_orig
();
...
...
@@ -629,6 +630,7 @@ void IdealGraphPrinter::visit_node(Node *n, void *param) {
}
print_prop
(
"debug_orig"
,
dorigStream
.
as_string
());
}
#endif
if
(
_chaitin
&&
_chaitin
!=
(
PhaseChaitin
*
)
0xdeadbeef
)
{
buffer
[
0
]
=
0
;
...
...
src/share/vm/prims/methodHandleWalk.cpp
浏览文件 @
59f3dfa2
...
...
@@ -265,7 +265,7 @@ MethodHandleWalker::walk(TRAPS) {
assert
(
dest
==
arg_state
->
_type
,
""
);
ArgToken
arg
=
arg_state
->
_arg
;
ArgToken
new_arg
=
make_conversion
(
T_OBJECT
,
dest_klass
,
Bytecodes
::
_checkcast
,
arg
,
CHECK_
(
empty
));
assert
(
arg
.
token_type
()
>=
tt_symbolic
||
arg
.
index
()
==
new_arg
.
index
(),
"should be the same index"
);
assert
(
!
arg
.
has_index
()
||
arg
.
index
()
==
new_arg
.
index
(),
"should be the same index"
);
debug_only
(
dest_klass
=
(
klassOop
)
badOop
);
break
;
}
...
...
@@ -443,8 +443,10 @@ MethodHandleWalker::walk(TRAPS) {
ret
=
make_conversion
(
T_OBJECT
,
rklass
,
Bytecodes
::
_checkcast
,
ret
,
CHECK_
(
empty
));
}
}
int
ret_slot
=
arg_slot
+
(
retain_original_args
?
coll_slots
:
0
);
change_argument
(
T_VOID
,
ret_slot
,
rtype
,
ret
);
if
(
rtype
!=
T_VOID
)
{
int
ret_slot
=
arg_slot
+
(
retain_original_args
?
coll_slots
:
0
);
change_argument
(
T_VOID
,
ret_slot
,
rtype
,
ret
);
}
break
;
}
...
...
@@ -690,9 +692,8 @@ void MethodHandleWalker::retype_raw_conversion(BasicType src, BasicType dst, boo
// -----------------------------------------------------------------------------
// MethodHandleCompiler
MethodHandleCompiler
::
MethodHandleCompiler
(
Handle
root
,
methodHandle
calle
e
,
int
invoke_count
,
bool
is_invokedynamic
,
TRAPS
)
MethodHandleCompiler
::
MethodHandleCompiler
(
Handle
root
,
Symbol
*
name
,
Symbol
*
signatur
e
,
int
invoke_count
,
bool
is_invokedynamic
,
TRAPS
)
:
MethodHandleWalker
(
root
,
is_invokedynamic
,
THREAD
),
_callee
(
callee
),
_invoke_count
(
invoke_count
),
_thread
(
THREAD
),
_bytecode
(
THREAD
,
50
),
...
...
@@ -706,8 +707,8 @@ MethodHandleCompiler::MethodHandleCompiler(Handle root, methodHandle callee, int
(
void
)
_constants
.
append
(
NULL
);
// Set name and signature index.
_name_index
=
cpool_symbol_put
(
_callee
->
name
()
);
_signature_index
=
cpool_symbol_put
(
_callee
->
signature
()
);
_name_index
=
cpool_symbol_put
(
name
);
_signature_index
=
cpool_symbol_put
(
signature
);
// Get return type klass.
Handle
first_mtype
(
THREAD
,
chain
().
method_type_oop
());
...
...
@@ -715,7 +716,8 @@ MethodHandleCompiler::MethodHandleCompiler(Handle root, methodHandle callee, int
_rtype
=
java_lang_Class
::
as_BasicType
(
java_lang_invoke_MethodType
::
rtype
(
first_mtype
()),
&
_rklass
);
if
(
_rtype
==
T_ARRAY
)
_rtype
=
T_OBJECT
;
int
params
=
_callee
->
size_of_parameters
();
// Incoming arguments plus receiver.
ArgumentSizeComputer
args
(
signature
);
int
params
=
args
.
size
()
+
1
;
// Incoming arguments plus receiver.
_num_params
=
for_invokedynamic
()
?
params
-
1
:
params
;
// XXX Check if callee is static?
}
...
...
@@ -733,7 +735,7 @@ methodHandle MethodHandleCompiler::compile(TRAPS) {
}
void
MethodHandleCompiler
::
emit_bc
(
Bytecodes
::
Code
op
,
int
index
)
{
void
MethodHandleCompiler
::
emit_bc
(
Bytecodes
::
Code
op
,
int
index
,
int
args_size
)
{
Bytecodes
::
check
(
op
);
// Are we legal?
switch
(
op
)
{
...
...
@@ -809,6 +811,14 @@ void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) {
case
Bytecodes
::
_d2i
:
case
Bytecodes
::
_d2l
:
case
Bytecodes
::
_d2f
:
case
Bytecodes
::
_iaload
:
case
Bytecodes
::
_laload
:
case
Bytecodes
::
_faload
:
case
Bytecodes
::
_daload
:
case
Bytecodes
::
_aaload
:
case
Bytecodes
::
_baload
:
case
Bytecodes
::
_caload
:
case
Bytecodes
::
_saload
:
case
Bytecodes
::
_ireturn
:
case
Bytecodes
::
_lreturn
:
case
Bytecodes
::
_freturn
:
...
...
@@ -822,9 +832,14 @@ void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) {
// bi
case
Bytecodes
::
_ldc
:
assert
(
Bytecodes
::
format_bits
(
op
,
false
)
==
(
Bytecodes
::
_fmt_b
|
Bytecodes
::
_fmt_has_k
),
"wrong bytecode format"
);
assert
((
char
)
index
==
index
,
"index does not fit in 8-bit"
);
_bytecode
.
push
(
op
);
_bytecode
.
push
(
index
);
if
(
index
==
(
index
&
0xff
))
{
_bytecode
.
push
(
op
);
_bytecode
.
push
(
index
);
}
else
{
_bytecode
.
push
(
Bytecodes
::
_ldc_w
);
_bytecode
.
push
(
index
>>
8
);
_bytecode
.
push
(
index
);
}
break
;
case
Bytecodes
::
_iload
:
...
...
@@ -838,9 +853,16 @@ void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) {
case
Bytecodes
::
_dstore
:
case
Bytecodes
::
_astore
:
assert
(
Bytecodes
::
format_bits
(
op
,
false
)
==
Bytecodes
::
_fmt_bi
,
"wrong bytecode format"
);
assert
((
char
)
index
==
index
,
"index does not fit in 8-bit"
);
_bytecode
.
push
(
op
);
_bytecode
.
push
(
index
);
if
(
index
==
(
index
&
0xff
))
{
_bytecode
.
push
(
op
);
_bytecode
.
push
(
index
);
}
else
{
// doesn't fit in a u2
_bytecode
.
push
(
Bytecodes
::
_wide
);
_bytecode
.
push
(
op
);
_bytecode
.
push
(
index
>>
8
);
_bytecode
.
push
(
index
);
}
break
;
// bkk
...
...
@@ -848,7 +870,7 @@ void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) {
case
Bytecodes
::
_ldc2_w
:
case
Bytecodes
::
_checkcast
:
assert
(
Bytecodes
::
format_bits
(
op
,
false
)
==
Bytecodes
::
_fmt_bkk
,
"wrong bytecode format"
);
assert
((
short
)
index
==
index
,
"index does not fit in 16-bit"
);
assert
((
unsigned
short
)
index
==
index
,
"index does not fit in 16-bit"
);
_bytecode
.
push
(
op
);
_bytecode
.
push
(
index
>>
8
);
_bytecode
.
push
(
index
);
...
...
@@ -859,12 +881,23 @@ void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) {
case
Bytecodes
::
_invokespecial
:
case
Bytecodes
::
_invokevirtual
:
assert
(
Bytecodes
::
format_bits
(
op
,
false
)
==
Bytecodes
::
_fmt_bJJ
,
"wrong bytecode format"
);
assert
((
short
)
index
==
index
,
"index does not fit in 16-bit"
);
assert
((
unsigned
short
)
index
==
index
,
"index does not fit in 16-bit"
);
_bytecode
.
push
(
op
);
_bytecode
.
push
(
index
>>
8
);
_bytecode
.
push
(
index
);
break
;
case
Bytecodes
::
_invokeinterface
:
assert
(
Bytecodes
::
format_bits
(
op
,
false
)
==
Bytecodes
::
_fmt_bJJ
,
"wrong bytecode format"
);
assert
((
unsigned
short
)
index
==
index
,
"index does not fit in 16-bit"
);
assert
(
args_size
>
0
,
"valid args_size"
);
_bytecode
.
push
(
op
);
_bytecode
.
push
(
index
>>
8
);
_bytecode
.
push
(
index
);
_bytecode
.
push
(
args_size
);
_bytecode
.
push
(
0
);
break
;
default:
ShouldNotReachHere
();
}
...
...
@@ -983,7 +1016,8 @@ MethodHandleCompiler::make_conversion(BasicType type, klassOop tk, Bytecodes::Co
const
ArgToken
&
src
,
TRAPS
)
{
BasicType
srctype
=
src
.
basic_type
();
int
index
=
src
.
index
();
TokenType
tt
=
src
.
token_type
();
int
index
=
-
1
;
switch
(
op
)
{
case
Bytecodes
::
_i2l
:
...
...
@@ -1004,18 +1038,31 @@ MethodHandleCompiler::make_conversion(BasicType type, klassOop tk, Bytecodes::Co
case
Bytecodes
::
_d2i
:
case
Bytecodes
::
_d2l
:
case
Bytecodes
::
_d2f
:
emit_load
(
srctype
,
index
);
if
(
tt
==
tt_constant
)
{
emit_load_constant
(
src
);
}
else
{
emit_load
(
srctype
,
src
.
index
());
}
stack_pop
(
srctype
);
// pop the src type
emit_bc
(
op
);
stack_push
(
type
);
// push the dest value
if
(
srctype
!=
type
)
if
(
tt
!=
tt_constant
)
index
=
src
.
index
();
if
(
srctype
!=
type
||
index
==
-
1
)
index
=
new_local_index
(
type
);
emit_store
(
type
,
index
);
break
;
case
Bytecodes
::
_checkcast
:
emit_load
(
srctype
,
index
);
if
(
tt
==
tt_constant
)
{
emit_load_constant
(
src
);
}
else
{
emit_load
(
srctype
,
src
.
index
());
index
=
src
.
index
();
}
emit_bc
(
op
,
cpool_klass_put
(
tk
));
if
(
index
==
-
1
)
index
=
new_local_index
(
type
);
emit_store
(
srctype
,
index
);
break
;
...
...
@@ -1058,6 +1105,11 @@ MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
Symbol
*
name
=
m
->
name
();
Symbol
*
signature
=
m
->
signature
();
// Count the number of arguments, not the size
ArgumentCount
asc
(
signature
);
assert
(
argc
==
asc
.
size
()
+
((
op
==
Bytecodes
::
_invokestatic
||
op
==
Bytecodes
::
_invokedynamic
)
?
0
:
1
),
"argc mismatch"
);
if
(
tailcall
)
{
// Actually, in order to make these methods more recognizable,
// let's put them in holder class MethodHandle. That way stack
...
...
@@ -1106,9 +1158,13 @@ MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
case
Bytecodes
::
_invokevirtual
:
emit_bc
(
op
,
methodref_index
);
break
;
case
Bytecodes
::
_invokeinterface
:
Unimplemented
();
case
Bytecodes
::
_invokeinterface
:
{
ArgumentSizeComputer
asc
(
signature
);
emit_bc
(
op
,
methodref_index
,
asc
.
size
()
+
1
);
break
;
}
default:
ShouldNotReachHere
();
}
...
...
@@ -1117,6 +1173,7 @@ MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
// Otherwise, make a recursive call to some helper routine.
BasicType
rbt
=
m
->
result_type
();
if
(
rbt
==
T_ARRAY
)
rbt
=
T_OBJECT
;
stack_push
(
rbt
);
// The return value is already pushed onto the stack.
ArgToken
ret
;
if
(
tailcall
)
{
if
(
rbt
!=
_rtype
)
{
...
...
@@ -1171,7 +1228,6 @@ MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
ret
=
ArgToken
();
// Dummy return value.
}
else
{
stack_push
(
rbt
);
// The return value is already pushed onto the stack.
int
index
=
new_local_index
(
rbt
);
switch
(
rbt
)
{
case
T_BOOLEAN
:
case
T_BYTE
:
case
T_CHAR
:
case
T_SHORT
:
...
...
@@ -1196,8 +1252,32 @@ MethodHandleCompiler::make_fetch(BasicType type, klassOop tk, Bytecodes::Code op
const
MethodHandleWalker
::
ArgToken
&
base
,
const
MethodHandleWalker
::
ArgToken
&
offset
,
TRAPS
)
{
Unimplemented
();
return
ArgToken
();
switch
(
base
.
token_type
())
{
case
tt_parameter
:
case
tt_temporary
:
emit_load
(
base
.
basic_type
(),
base
.
index
());
break
;
case
tt_constant
:
emit_load_constant
(
base
);
break
;
default:
ShouldNotReachHere
();
}
switch
(
offset
.
token_type
())
{
case
tt_parameter
:
case
tt_temporary
:
emit_load
(
offset
.
basic_type
(),
offset
.
index
());
break
;
case
tt_constant
:
emit_load_constant
(
offset
);
break
;
default:
ShouldNotReachHere
();
}
emit_bc
(
op
);
int
index
=
new_local_index
(
type
);
emit_store
(
type
,
index
);
return
ArgToken
(
tt_temporary
,
type
,
index
);
}
...
...
@@ -1372,12 +1452,10 @@ private:
return
s
;
}
ArgToken
token
(
const
char
*
str
)
{
jvalue
string_con
;
string_con
.
j
=
(
intptr_t
)
str
;
return
ArgToken
(
tt_symbolic
,
T_LONG
,
string_con
);
return
ArgToken
(
str
);
}
const
char
*
string
(
ArgToken
token
)
{
return
(
const
char
*
)
(
intptr_t
)
token
.
get_jlong
();
return
token
.
str
();
}
void
start_params
()
{
_param_state
<<=
1
;
...
...
src/share/vm/prims/methodHandleWalk.hpp
浏览文件 @
59f3dfa2
...
...
@@ -126,26 +126,34 @@ public:
Handle
_handle
;
public:
ArgToken
(
TokenType
tt
=
tt_illegal
)
:
_tt
(
tt
)
{}
ArgToken
(
TokenType
tt
,
BasicType
bt
,
jvalue
value
)
:
_tt
(
tt
),
_bt
(
bt
),
_value
(
value
)
{}
ArgToken
(
TokenType
tt
=
tt_illegal
)
:
_tt
(
tt
)
{
assert
(
tt
==
tt_illegal
||
tt
==
tt_void
,
"invalid token type"
);
}
ArgToken
(
TokenType
tt
,
BasicType
bt
,
int
index
)
:
_tt
(
tt
),
_bt
(
bt
)
{
assert
(
_tt
==
tt_parameter
||
_tt
==
tt_temporary
,
"must have index"
);
_value
.
i
=
index
;
}
ArgToken
(
TokenType
tt
,
BasicType
bt
,
Handle
value
)
:
_tt
(
tt
),
_bt
(
bt
)
{
_handle
=
value
;
ArgToken
(
BasicType
bt
,
jvalue
value
)
:
_tt
(
tt_constant
),
_bt
(
bt
),
_value
(
value
)
{}
ArgToken
(
BasicType
bt
,
Handle
value
)
:
_tt
(
tt_constant
),
_bt
(
bt
),
_handle
(
value
)
{}
ArgToken
(
const
char
*
str
)
:
_tt
(
tt_symbolic
),
_bt
(
T_LONG
)
{
_value
.
j
=
(
intptr_t
)
str
;
}
TokenType
token_type
()
const
{
return
_tt
;
}
BasicType
basic_type
()
const
{
return
_bt
;
}
int
index
()
const
{
return
_value
.
i
;
}
Handle
object
()
const
{
return
_handle
;
}
jint
get_jint
()
const
{
return
_value
.
i
;
}
jlong
get_jlong
()
const
{
return
_value
.
j
;
}
jfloat
get_jfloat
()
const
{
return
_value
.
f
;
}
jdouble
get_jdouble
()
const
{
return
_value
.
d
;
}
bool
has_index
()
const
{
return
_tt
==
tt_parameter
||
_tt
==
tt_temporary
;
}
int
index
()
const
{
assert
(
has_index
(),
"must have index"
);;
return
_value
.
i
;
}
Handle
object
()
const
{
assert
(
_tt
==
tt_constant
,
"value type"
);
return
_handle
;
}
const
char
*
str
()
const
{
assert
(
_tt
==
tt_symbolic
,
"string type"
);
return
(
const
char
*
)
_value
.
j
;
}
jint
get_jint
()
const
{
assert
(
_tt
==
tt_constant
,
"value types"
);
return
_value
.
i
;
}
jlong
get_jlong
()
const
{
assert
(
_tt
==
tt_constant
,
"value types"
);
return
_value
.
j
;
}
jfloat
get_jfloat
()
const
{
assert
(
_tt
==
tt_constant
,
"value types"
);
return
_value
.
f
;
}
jdouble
get_jdouble
()
const
{
assert
(
_tt
==
tt_constant
,
"value types"
);
return
_value
.
d
;
}
};
// Abstract interpretation state:
...
...
@@ -256,7 +264,6 @@ public:
// The IR happens to be JVM bytecodes.
class
MethodHandleCompiler
:
public
MethodHandleWalker
{
private:
methodHandle
_callee
;
int
_invoke_count
;
// count the original call site has been executed
KlassHandle
_rklass
;
// Return type for casting.
BasicType
_rtype
;
...
...
@@ -404,7 +411,7 @@ private:
return
cpool_oop_reference_put
(
JVM_CONSTANT_NameAndType
,
name_index
,
signature_index
);
}
void
emit_bc
(
Bytecodes
::
Code
op
,
int
index
=
0
);
void
emit_bc
(
Bytecodes
::
Code
op
,
int
index
=
0
,
int
args_size
=
-
1
);
void
emit_load
(
BasicType
bt
,
int
index
);
void
emit_store
(
BasicType
bt
,
int
index
);
void
emit_load_constant
(
ArgToken
arg
);
...
...
@@ -414,10 +421,10 @@ private:
}
virtual
ArgToken
make_oop_constant
(
oop
con
,
TRAPS
)
{
Handle
h
(
THREAD
,
con
);
return
ArgToken
(
tt_constant
,
T_OBJECT
,
h
);
return
ArgToken
(
T_OBJECT
,
h
);
}
virtual
ArgToken
make_prim_constant
(
BasicType
type
,
jvalue
*
con
,
TRAPS
)
{
return
ArgToken
(
t
t_constant
,
t
ype
,
*
con
);
return
ArgToken
(
type
,
*
con
);
}
virtual
ArgToken
make_conversion
(
BasicType
type
,
klassOop
tk
,
Bytecodes
::
Code
op
,
const
ArgToken
&
src
,
TRAPS
);
...
...
@@ -431,7 +438,7 @@ private:
methodHandle
get_method_oop
(
TRAPS
)
const
;
public:
MethodHandleCompiler
(
Handle
root
,
methodHandle
calle
e
,
int
invoke_count
,
bool
for_invokedynamic
,
TRAPS
);
MethodHandleCompiler
(
Handle
root
,
Symbol
*
name
,
Symbol
*
signatur
e
,
int
invoke_count
,
bool
for_invokedynamic
,
TRAPS
);
// Compile the given MH chain into bytecode.
methodHandle
compile
(
TRAPS
);
...
...
src/share/vm/prims/methodHandles.cpp
浏览文件 @
59f3dfa2
...
...
@@ -25,9 +25,11 @@
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/oopMapCache.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "prims/methodHandles.hpp"
#include "prims/methodHandleWalk.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/reflection.hpp"
#include "runtime/signature.hpp"
...
...
@@ -2599,6 +2601,50 @@ void MethodHandles::ensure_vmlayout_field(Handle target, TRAPS) {
}
}
#ifdef ASSERT
extern
"C"
void
print_method_handle
(
oop
mh
);
static
void
stress_method_handle_walk_impl
(
Handle
mh
,
TRAPS
)
{
if
(
StressMethodHandleWalk
)
{
// Exercise the MethodHandleWalk code in various ways and validate
// the resulting method oop. Some of these produce output so they
// are guarded under Verbose.
ResourceMark
rm
;
HandleMark
hm
;
if
(
Verbose
)
{
print_method_handle
(
mh
());
}
TempNewSymbol
name
=
SymbolTable
::
new_symbol
(
"invoke"
,
CHECK
);
Handle
mt
=
java_lang_invoke_MethodHandle
::
type
(
mh
());
TempNewSymbol
signature
=
java_lang_invoke_MethodType
::
as_signature
(
mt
(),
true
,
CHECK
);
MethodHandleCompiler
mhc
(
mh
,
name
,
signature
,
10000
,
false
,
CHECK
);
methodHandle
m
=
mhc
.
compile
(
CHECK
);
if
(
Verbose
)
{
m
->
print_codes
();
}
InterpreterOopMap
mask
;
OopMapCache
::
compute_one_oop_map
(
m
,
m
->
code_size
()
-
1
,
&
mask
);
}
}
static
void
stress_method_handle_walk
(
Handle
mh
,
TRAPS
)
{
stress_method_handle_walk_impl
(
mh
,
THREAD
);
if
(
HAS_PENDING_EXCEPTION
)
{
oop
ex
=
PENDING_EXCEPTION
;
CLEAR_PENDING_EXCEPTION
;
tty
->
print
(
"StressMethodHandleWalk: "
);
java_lang_Throwable
::
print
(
ex
,
tty
);
tty
->
cr
();
}
}
#else
static
void
stress_method_handle_walk
(
Handle
mh
,
TRAPS
)
{}
#endif
//
// Here are the native methods on sun.invoke.MethodHandleImpl.
// They are the private interface between this JVM and the HotSpot-specific
...
...
@@ -2666,6 +2712,7 @@ JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
}
MethodHandles
::
init_DirectMethodHandle
(
mh
,
m
,
(
do_dispatch
!=
JNI_FALSE
),
CHECK
);
stress_method_handle_walk
(
mh
,
CHECK
);
}
JVM_END
...
...
@@ -2694,11 +2741,11 @@ JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
receiver_limit
,
decode_flags
,
CHECK
);
return
;
}
else
{
// Build a BMH on top of a DMH or another BMH:
MethodHandles
::
init_BoundMethodHandle
(
mh
,
target
,
argnum
,
CHECK
);
}
// Build a BMH on top of a DMH or another BMH:
MethodHandles
::
init_BoundMethodHandle
(
mh
,
target
,
argnum
,
CHECK
);
stress_method_handle_walk
(
mh
,
CHECK
);
}
JVM_END
...
...
@@ -2716,6 +2763,7 @@ JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
assert
(
java_lang_invoke_MethodHandle
::
vmentry
(
mh
())
==
NULL
,
"must be safely null"
);
MethodHandles
::
init_AdapterMethodHandle
(
mh
,
target
,
argnum
,
CHECK
);
stress_method_handle_walk
(
mh
,
CHECK
);
}
JVM_END
...
...
src/share/vm/runtime/globals.hpp
浏览文件 @
59f3dfa2
...
...
@@ -3724,6 +3724,9 @@ class CommandLineFlags {
diagnostic(bool, OptimizeMethodHandles, true, \
"when constructing method handles, try to improve them") \
\
develop(bool, StressMethodHandleWalk, false, \
"Process all method handles with MethodHandleWalk") \
\
diagnostic(bool, UseRicochetFrames, true, \
"use ricochet stack frames for method handle combination, " \
"if the platform supports them") \
...
...
src/share/vm/runtime/thread.cpp
浏览文件 @
59f3dfa2
...
...
@@ -2861,6 +2861,7 @@ void JavaThread::trace_frames() {
}
#ifdef ASSERT
// Print or validate the layout of stack frames
void
JavaThread
::
print_frame_layout
(
int
depth
,
bool
validate_only
)
{
ResourceMark
rm
;
...
...
@@ -2878,7 +2879,7 @@ void JavaThread::print_frame_layout(int depth, bool validate_only) {
values
.
print
();
}
}
#endif
void
JavaThread
::
trace_stack_from
(
vframe
*
start_vf
)
{
ResourceMark
rm
;
...
...
src/share/vm/runtime/vmStructs.cpp
浏览文件 @
59f3dfa2
...
...
@@ -783,6 +783,7 @@ static inline uint64_t cast_uint64_t(size_t x)
nonstatic_field(nmethod, _osr_link, nmethod*) \
nonstatic_field(nmethod, _scavenge_root_link, nmethod*) \
nonstatic_field(nmethod, _scavenge_root_state, jbyte) \
nonstatic_field(nmethod, _state, unsigned char) \
nonstatic_field(nmethod, _exception_offset, int) \
nonstatic_field(nmethod, _deoptimize_offset, int) \
nonstatic_field(nmethod, _orig_pc_offset, int) \
...
...
@@ -800,6 +801,8 @@ static inline uint64_t cast_uint64_t(size_t x)
nonstatic_field(nmethod, _osr_entry_point, address) \
nonstatic_field(nmethod, _lock_count, jint) \
nonstatic_field(nmethod, _stack_traversal_mark, long) \
nonstatic_field(nmethod, _compile_id, int) \
nonstatic_field(nmethod, _marked_for_deoptimization, bool) \
\
/********************************/
\
/* JavaCalls (NOTE: incomplete) */
\
...
...
@@ -1310,11 +1313,13 @@ static inline uint64_t cast_uint64_t(size_t x)
\
declare_toplevel_type(CodeBlob) \
declare_type(BufferBlob, CodeBlob) \
declare_type(nmethod, CodeBlob) \
declare_type(AdapterBlob, BufferBlob) \
declare_type(nmethod, CodeBlob) \
declare_type(RuntimeStub, CodeBlob) \
declare_type(SingletonBlob, CodeBlob) \
declare_type(SafepointBlob, SingletonBlob) \
declare_type(DeoptimizationBlob, SingletonBlob) \
declare_type(RicochetBlob, SingletonBlob) \
declare_c2_type(ExceptionBlob, SingletonBlob) \
declare_c2_type(UncommonTrapBlob, CodeBlob) \
\
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录