Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
8f6f72b9
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看板
提交
8f6f72b9
编写于
12月 22, 2010
作者:
T
twisti
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
Reviewed-by: kvn, jrose
上级
c006d3f4
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
100 addition
and
98 deletion
+100
-98
src/cpu/sparc/vm/methodHandles_sparc.cpp
src/cpu/sparc/vm/methodHandles_sparc.cpp
+31
-39
src/cpu/x86/vm/methodHandles_x86.cpp
src/cpu/x86/vm/methodHandles_x86.cpp
+57
-49
src/share/vm/prims/methodHandles.cpp
src/share/vm/prims/methodHandles.cpp
+9
-4
src/share/vm/prims/methodHandles.hpp
src/share/vm/prims/methodHandles.hpp
+3
-3
src/share/vm/runtime/init.cpp
src/share/vm/runtime/init.cpp
+0
-3
未找到文件。
src/cpu/sparc/vm/methodHandles_sparc.cpp
浏览文件 @
8f6f72b9
...
...
@@ -395,18 +395,23 @@ int MethodHandles::adapter_conversion_ops_supported_mask() {
//
// Generate an "entry" field for a method handle.
// This determines how the method handle will respond to calls.
void
MethodHandles
::
generate_method_handle_stub
(
MacroAssembler
*
_masm
,
MethodHandles
::
EntryKind
ek
)
{
void
MethodHandles
::
generate_method_handle_stub
(
MacroAssembler
*
_masm
,
MethodHandles
::
EntryKind
ek
,
TRAPS
)
{
// Here is the register state during an interpreted call,
// as set up by generate_method_handle_interpreter_entry():
// - G5: garbage temp (was MethodHandle.invoke methodOop, unused)
// - G3: receiver method handle
// - O5_savedSP: sender SP (must preserve)
Register
O0_argslot
=
O0
;
Register
O1_scratch
=
O1
;
Register
O2_scratch
=
O2
;
Register
O3_scratch
=
O3
;
Register
G5_index
=
G5
;
const
Register
O0_argslot
=
O0
;
const
Register
O1_scratch
=
O1
;
const
Register
O2_scratch
=
O2
;
const
Register
O3_scratch
=
O3
;
const
Register
G5_index
=
G5
;
// Argument registers for _raise_exception.
const
Register
O0_code
=
O0
;
const
Register
O1_actual
=
O1
;
const
Register
O2_required
=
O2
;
guarantee
(
java_dyn_MethodHandle
::
vmentry_offset_in_bytes
()
!=
0
,
"must have offsets"
);
...
...
@@ -439,48 +444,36 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
case
_raise_exception
:
{
// Not a real MH entry, but rather shared code for raising an
// exception. Extra local arguments are passed in scratch
// registers, as required type in O3, failing object (or NULL)
// in O2, failing bytecode type in O1.
// exception. Since we use a C2I adapter to set up the
// interpreter state, arguments are expected in compiler
// argument registers.
methodHandle
mh
(
raise_exception_method
());
address
c2i_entry
=
methodOopDesc
::
make_adapters
(
mh
,
CATCH
);
__
mov
(
O5_savedSP
,
SP
);
// Cut the stack back to where the caller started.
// Push arguments as if coming from the interpreter.
Register
O0_scratch
=
O0_argslot
;
int
stackElementSize
=
Interpreter
::
stackElementSize
;
// Make space on the stack for the arguments and set Gargs
// correctly.
__
sub
(
SP
,
4
*
stackElementSize
,
SP
);
// Keep stack aligned.
__
add
(
SP
,
(
frame
::
varargs_offset
)
*
wordSize
-
1
*
Interpreter
::
stackElementSize
+
STACK_BIAS
+
BytesPerWord
,
Gargs
);
// void raiseException(int code, Object actual, Object required)
__
st
(
O1_scratch
,
Address
(
Gargs
,
2
*
stackElementSize
));
// code
__
st_ptr
(
O2_scratch
,
Address
(
Gargs
,
1
*
stackElementSize
));
// actual
__
st_ptr
(
O3_scratch
,
Address
(
Gargs
,
0
*
stackElementSize
));
// required
Label
no_method
;
Label
L_no_method
;
// FIXME: fill in _raise_exception_method with a suitable sun.dyn method
__
set
(
AddressLiteral
((
address
)
&
_raise_exception_method
),
G5_method
);
__
ld_ptr
(
Address
(
G5_method
,
0
),
G5_method
);
__
tst
(
G5_method
);
__
brx
(
Assembler
::
zero
,
false
,
Assembler
::
pn
,
no_method
);
__
brx
(
Assembler
::
zero
,
false
,
Assembler
::
pn
,
L_
no_method
);
__
delayed
()
->
nop
();
int
jobject_oop_offset
=
0
;
const
int
jobject_oop_offset
=
0
;
__
ld_ptr
(
Address
(
G5_method
,
jobject_oop_offset
),
G5_method
);
__
tst
(
G5_method
);
__
brx
(
Assembler
::
zero
,
false
,
Assembler
::
pn
,
no_method
);
__
brx
(
Assembler
::
zero
,
false
,
Assembler
::
pn
,
L_
no_method
);
__
delayed
()
->
nop
();
__
verify_oop
(
G5_method
);
__
jump_
indirect_to
(
G5_method_fie
,
O1
_scratch
);
__
jump_
to
(
AddressLiteral
(
c2i_entry
),
O3
_scratch
);
__
delayed
()
->
nop
();
// If we get here, the Java runtime did not do its job of creating the exception.
// Do something that is at least causes a valid throw from the interpreter.
__
bind
(
no_method
);
__
unimplemented
(
"
_raise_exception no method
"
);
__
bind
(
L_
no_method
);
__
unimplemented
(
"
call throw_WrongMethodType_entry
"
);
}
break
;
...
...
@@ -570,10 +563,10 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
// Throw an exception.
// For historical reasons, it will be IncompatibleClassChangeError.
__
unimplemented
(
"not tested yet"
);
__
ld_ptr
(
Address
(
O1_intf
,
java_mirror_offset
),
O
3_scratch
);
// required interface
__
mov
(
O0_klass
,
O2_scratch
);
// bad receiver
__
jump_to
(
AddressLiteral
(
from_interpreted_entry
(
_raise_exception
)),
O
0_argslot
);
__
delayed
()
->
mov
(
Bytecodes
::
_invokeinterface
,
O1_scratch
);
// who is complaining?
__
ld_ptr
(
Address
(
O1_intf
,
java_mirror_offset
),
O
2_required
);
// required interface
__
mov
(
O0_klass
,
O1_actual
);
// bad receiver
__
jump_to
(
AddressLiteral
(
from_interpreted_entry
(
_raise_exception
)),
O
3_scratch
);
__
delayed
()
->
mov
(
Bytecodes
::
_invokeinterface
,
O0_code
);
// who is complaining?
}
break
;
...
...
@@ -663,11 +656,10 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
__
check_klass_subtype
(
O1_scratch
,
G5_klass
,
O0_argslot
,
O2_scratch
,
done
);
// If we get here, the type check failed!
__
ldsw
(
G3_amh_vmargslot
,
O0_argslot
);
// reload argslot field
__
load_heap_oop
(
G3_amh_argument
,
O3_scratch
);
// required class
__
ld_ptr
(
vmarg
,
O2_scratch
);
// bad object
__
jump_to
(
AddressLiteral
(
from_interpreted_entry
(
_raise_exception
)),
O0_argslot
);
__
delayed
()
->
mov
(
Bytecodes
::
_checkcast
,
O1_scratch
);
// who is complaining?
__
load_heap_oop
(
G3_amh_argument
,
O2_required
);
// required class
__
ld_ptr
(
vmarg
,
O1_actual
);
// bad object
__
jump_to
(
AddressLiteral
(
from_interpreted_entry
(
_raise_exception
)),
O3_scratch
);
__
delayed
()
->
mov
(
Bytecodes
::
_checkcast
,
O0_code
);
// who is complaining?
__
bind
(
done
);
// Get the new MH:
...
...
src/cpu/x86/vm/methodHandles_x86.cpp
浏览文件 @
8f6f72b9
...
...
@@ -385,9 +385,12 @@ int MethodHandles::adapter_conversion_ops_supported_mask() {
// FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
}
//------------------------------------------------------------------------------
// MethodHandles::generate_method_handle_stub
//
// Generate an "entry" field for a method handle.
// This determines how the method handle will respond to calls.
void
MethodHandles
::
generate_method_handle_stub
(
MacroAssembler
*
_masm
,
MethodHandles
::
EntryKind
ek
)
{
void
MethodHandles
::
generate_method_handle_stub
(
MacroAssembler
*
_masm
,
MethodHandles
::
EntryKind
ek
,
TRAPS
)
{
// Here is the register state during an interpreted call,
// as set up by generate_method_handle_interpreter_entry():
// - rbx: garbage temp (was MethodHandle.invoke methodOop, unused)
...
...
@@ -396,14 +399,21 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
// - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
// - rdx: garbage temp, can blow away
Register
rcx_recv
=
rcx
;
Register
rax_argslot
=
rax
;
Register
rbx_temp
=
rbx
;
Register
rdx_temp
=
rdx
;
const
Register
rcx_recv
=
rcx
;
const
Register
rax_argslot
=
rax
;
const
Register
rbx_temp
=
rbx
;
const
Register
rdx_temp
=
rdx
;
// This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
// and gen_c2i_adapter (from compiled calls):
Register
saved_last_sp
=
LP64_ONLY
(
r13
)
NOT_LP64
(
rsi
);
const
Register
saved_last_sp
=
LP64_ONLY
(
r13
)
NOT_LP64
(
rsi
);
// Argument registers for _raise_exception.
// 32-bit: Pass first two oop/int args in registers ECX and EDX.
const
Register
rarg0_code
=
LP64_ONLY
(
j_rarg0
)
NOT_LP64
(
rcx
);
const
Register
rarg1_actual
=
LP64_ONLY
(
j_rarg1
)
NOT_LP64
(
rdx
);
const
Register
rarg2_required
=
LP64_ONLY
(
j_rarg2
)
NOT_LP64
(
rdi
);
assert_different_registers
(
rarg0_code
,
rarg1_actual
,
rarg2_required
,
saved_last_sp
);
guarantee
(
java_dyn_MethodHandle
::
vmentry_offset_in_bytes
()
!=
0
,
"must have offsets"
);
...
...
@@ -437,47 +447,41 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
switch
((
int
)
ek
)
{
case
_raise_exception
:
{
// Not a real MH entry, but rather shared code for raising an exception.
// Extra local arguments are pushed on stack, as required type at TOS+8,
// failing object (or NULL) at TOS+4, failing bytecode type at TOS.
// Beyond those local arguments are the PC, of course.
Register
rdx_code
=
rdx_temp
;
Register
rcx_fail
=
rcx_recv
;
Register
rax_want
=
rax_argslot
;
Register
rdi_pc
=
rdi
;
__
pop
(
rdx_code
);
// TOS+0
__
pop
(
rcx_fail
);
// TOS+4
__
pop
(
rax_want
);
// TOS+8
__
pop
(
rdi_pc
);
// caller PC
__
mov
(
rsp
,
rsi
);
// cut the stack back to where the caller started
// Repush the arguments as if coming from the interpreter.
__
push
(
rdx_code
);
__
push
(
rcx_fail
);
__
push
(
rax_want
);
// Not a real MH entry, but rather shared code for raising an
// exception. Since we use a C2I adapter to set up the
// interpreter state, arguments are expected in compiler
// argument registers.
methodHandle
mh
(
raise_exception_method
());
address
c2i_entry
=
methodOopDesc
::
make_adapters
(
mh
,
CHECK
);
const
Register
rdi_pc
=
rax
;
__
pop
(
rdi_pc
);
// caller PC
__
mov
(
rsp
,
saved_last_sp
);
// cut the stack back to where the caller started
Register
rbx_method
=
rbx_temp
;
Label
no_method
;
Label
L_
no_method
;
// FIXME: fill in _raise_exception_method with a suitable sun.dyn method
__
movptr
(
rbx_method
,
ExternalAddress
((
address
)
&
_raise_exception_method
));
__
testptr
(
rbx_method
,
rbx_method
);
__
jccb
(
Assembler
::
zero
,
no_method
);
int
jobject_oop_offset
=
0
;
__
jccb
(
Assembler
::
zero
,
L_no_method
);
const
int
jobject_oop_offset
=
0
;
__
movptr
(
rbx_method
,
Address
(
rbx_method
,
jobject_oop_offset
));
// dereference the jobject
__
testptr
(
rbx_method
,
rbx_method
);
__
jccb
(
Assembler
::
zero
,
no_method
);
__
jccb
(
Assembler
::
zero
,
L_
no_method
);
__
verify_oop
(
rbx_method
);
__
push
(
rdi_pc
);
// and restore caller PC
__
jmp
(
rbx_method_fie
);
// 32-bit: push remaining arguments as if coming from the compiler.
NOT_LP64
(
__
push
(
rarg2_required
));
__
push
(
rdi_pc
);
// restore caller PC
__
jump
(
ExternalAddress
(
c2i_entry
));
// do C2I transition
// If we get here, the Java runtime did not do its job of creating the exception.
// Do something that is at least causes a valid throw from the interpreter.
__
bind
(
no_method
);
__
pop
(
rax_want
);
__
pop
(
rcx_fail
);
__
push
(
rax_want
);
__
push
(
rcx_fail
);
__
bind
(
L_no_method
);
__
push
(
rarg2_required
);
__
push
(
rarg1_actual
);
__
jump
(
ExternalAddress
(
Interpreter
::
throw_WrongMethodType_entry
()));
}
break
;
...
...
@@ -572,9 +576,11 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
__
bind
(
no_such_interface
);
// Throw an exception.
// For historical reasons, it will be IncompatibleClassChangeError.
__
pushptr
(
Address
(
rdx_intf
,
java_mirror_offset
));
// required interface
__
push
(
rcx_recv
);
// bad receiver
__
push
((
int
)
Bytecodes
::
_invokeinterface
);
// who is complaining?
__
mov
(
rbx_temp
,
rcx_recv
);
// rarg2_required might be RCX
assert_different_registers
(
rarg2_required
,
rbx_temp
);
__
movptr
(
rarg2_required
,
Address
(
rdx_intf
,
java_mirror_offset
));
// required interface
__
mov
(
rarg1_actual
,
rbx_temp
);
// bad receiver
__
movl
(
rarg0_code
,
(
int
)
Bytecodes
::
_invokeinterface
);
// who is complaining?
__
jump
(
ExternalAddress
(
from_interpreted_entry
(
_raise_exception
)));
}
break
;
...
...
@@ -669,10 +675,10 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
__
movl
(
rax_argslot
,
rcx_amh_vmargslot
);
// reload argslot field
__
movptr
(
rdx_temp
,
vmarg
);
__
load_heap_oop
(
rbx_klass
,
rcx_amh_argument
);
// required class
__
push
(
rbx_klass
);
__
push
(
rdx_temp
);
// bad object
__
push
((
int
)
Bytecodes
::
_checkcast
);
// who is complaining?
assert_different_registers
(
rarg2_required
,
rdx_temp
);
__
load_heap_oop
(
rarg2_required
,
rcx_amh_argument
);
// required class
__
mov
(
rarg1_actual
,
rdx_temp
);
// bad object
__
movl
(
rarg0_code
,
(
int
)
Bytecodes
::
_checkcast
);
// who is complaining?
__
jump
(
ExternalAddress
(
from_interpreted_entry
(
_raise_exception
)));
__
bind
(
done
);
...
...
@@ -1189,16 +1195,18 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
__
bind
(
bad_array_klass
);
UNPUSH_RSI_RDI
;
__
pushptr
(
Address
(
rdx_array_klass
,
java_mirror_offset
));
// required type
__
pushptr
(
vmarg
);
// bad array
__
push
((
int
)
Bytecodes
::
_aaload
);
// who is complaining?
assert
(
!
vmarg
.
uses
(
rarg2_required
),
"must be different registers"
);
__
movptr
(
rarg2_required
,
Address
(
rdx_array_klass
,
java_mirror_offset
));
// required type
__
movptr
(
rarg1_actual
,
vmarg
);
// bad array
__
movl
(
rarg0_code
,
(
int
)
Bytecodes
::
_aaload
);
// who is complaining?
__
jump
(
ExternalAddress
(
from_interpreted_entry
(
_raise_exception
)));
__
bind
(
bad_array_length
);
UNPUSH_RSI_RDI
;
__
push
(
rcx_recv
);
// AMH requiring a certain length
__
pushptr
(
vmarg
);
// bad array
__
push
((
int
)
Bytecodes
::
_arraylength
);
// who is complaining?
assert
(
!
vmarg
.
uses
(
rarg2_required
),
"must be different registers"
);
__
mov
(
rarg2_required
,
rcx_recv
);
// AMH requiring a certain length
__
movptr
(
rarg1_actual
,
vmarg
);
// bad array
__
movl
(
rarg0_code
,
(
int
)
Bytecodes
::
_arraylength
);
// who is complaining?
__
jump
(
ExternalAddress
(
from_interpreted_entry
(
_raise_exception
)));
#undef UNPUSH_RSI_RDI
...
...
src/share/vm/prims/methodHandles.cpp
浏览文件 @
8f6f72b9
...
...
@@ -111,7 +111,7 @@ bool MethodHandles::spot_check_entry_names() {
//------------------------------------------------------------------------------
// MethodHandles::generate_adapters
//
void
MethodHandles
::
generate_adapters
()
{
void
MethodHandles
::
generate_adapters
(
TRAPS
)
{
if
(
!
EnableMethodHandles
||
SystemDictionary
::
MethodHandle_klass
()
==
NULL
)
return
;
assert
(
_adapter_code
==
NULL
,
"generate only once"
);
...
...
@@ -123,20 +123,20 @@ void MethodHandles::generate_adapters() {
vm_exit_out_of_memory
(
_adapter_code_size
,
"CodeCache: no room for MethodHandles adapters"
);
CodeBuffer
code
(
_adapter_code
);
MethodHandlesAdapterGenerator
g
(
&
code
);
g
.
generate
();
g
.
generate
(
CHECK
);
}
//------------------------------------------------------------------------------
// MethodHandlesAdapterGenerator::generate
//
void
MethodHandlesAdapterGenerator
::
generate
()
{
void
MethodHandlesAdapterGenerator
::
generate
(
TRAPS
)
{
// Generate generic method handle adapters.
for
(
MethodHandles
::
EntryKind
ek
=
MethodHandles
::
_EK_FIRST
;
ek
<
MethodHandles
::
_EK_LIMIT
;
ek
=
MethodHandles
::
EntryKind
(
1
+
(
int
)
ek
))
{
StubCodeMark
mark
(
this
,
"MethodHandle"
,
MethodHandles
::
entry_name
(
ek
));
MethodHandles
::
generate_method_handle_stub
(
_masm
,
ek
);
MethodHandles
::
generate_method_handle_stub
(
_masm
,
ek
,
CHECK
);
}
}
...
...
@@ -2645,5 +2645,10 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
MethodHandles
::
set_enabled
(
true
);
}
}
// Generate method handles adapters if enabled.
if
(
MethodHandles
::
enabled
())
{
MethodHandles
::
generate_adapters
(
CHECK
);
}
}
JVM_END
src/share/vm/prims/methodHandles.hpp
浏览文件 @
8f6f72b9
...
...
@@ -294,11 +294,11 @@ class MethodHandles: AllStatic {
enum
{
_suppress_defc
=
1
,
_suppress_name
=
2
,
_suppress_type
=
4
};
// Generate MethodHandles adapters.
static
void
generate_adapters
();
static
void
generate_adapters
(
TRAPS
);
// Called from InterpreterGenerator and MethodHandlesAdapterGenerator.
static
address
generate_method_handle_interpreter_entry
(
MacroAssembler
*
_masm
);
static
void
generate_method_handle_stub
(
MacroAssembler
*
_masm
,
EntryKind
ek
);
static
void
generate_method_handle_stub
(
MacroAssembler
*
_masm
,
EntryKind
ek
,
TRAPS
);
// argument list parsing
static
int
argument_slot
(
oop
method_type
,
int
arg
);
...
...
@@ -530,7 +530,7 @@ class MethodHandlesAdapterGenerator : public StubCodeGenerator {
public:
MethodHandlesAdapterGenerator
(
CodeBuffer
*
code
)
:
StubCodeGenerator
(
code
)
{}
void
generate
();
void
generate
(
TRAPS
);
};
#endif // SHARE_VM_PRIMS_METHODHANDLES_HPP
src/share/vm/runtime/init.cpp
浏览文件 @
8f6f72b9
...
...
@@ -125,9 +125,6 @@ jint init_globals() {
javaClasses_init
();
// must happen after vtable initialization
stubRoutines_init2
();
// note: StubRoutines need 2-phase init
// Generate MethodHandles adapters.
MethodHandles
::
generate_adapters
();
// Although we'd like to, we can't easily do a heap verify
// here because the main thread isn't yet a JavaThread, so
// its TLAB may not be made parseable from the usual interfaces.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录