Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
e464b779
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看板
提交
e464b779
编写于
11月 28, 2017
作者:
M
mdoerr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8191907: PPC64 part of JDK-8174962: Better interface invocations
Reviewed-by: goetz
上级
2b04f898
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
117 addition
and
129 deletion
+117
-129
src/cpu/ppc/vm/macroAssembler_ppc.cpp
src/cpu/ppc/vm/macroAssembler_ppc.cpp
+25
-21
src/cpu/ppc/vm/macroAssembler_ppc.hpp
src/cpu/ppc/vm/macroAssembler_ppc.hpp
+4
-3
src/cpu/ppc/vm/templateTable_ppc_64.cpp
src/cpu/ppc/vm/templateTable_ppc_64.cpp
+38
-35
src/cpu/ppc/vm/vtableStubs_ppc_64.cpp
src/cpu/ppc/vm/vtableStubs_ppc_64.cpp
+50
-70
未找到文件。
src/cpu/ppc/vm/macroAssembler_ppc.cpp
浏览文件 @
e464b779
/*
/*
* Copyright (c) 1997, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 201
4
SAP AG. All rights reserved.
* Copyright 2012, 201
7
SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -1531,11 +1531,10 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -1531,11 +1531,10 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
RegisterOrConstant
itable_index
,
RegisterOrConstant
itable_index
,
Register
method_result
,
Register
method_result
,
Register
scan_temp
,
Register
scan_temp
,
Register
sethi_temp
,
Register
temp2
,
Label
&
L_no_such_interface
)
{
Label
&
L_no_such_interface
,
bool
return_method
)
{
assert_different_registers
(
recv_klass
,
intf_klass
,
method_result
,
scan_temp
);
assert_different_registers
(
recv_klass
,
intf_klass
,
method_result
,
scan_temp
);
assert
(
itable_index
.
is_constant
()
||
itable_index
.
as_register
()
==
method_result
,
"caller must use same register for non-constant itable index as for method"
);
// Compute start of first itableOffsetEntry (which is at the end of the vtable).
// Compute start of first itableOffsetEntry (which is at the end of the vtable).
int
vtable_base
=
InstanceKlass
::
vtable_start_offset
()
*
wordSize
;
int
vtable_base
=
InstanceKlass
::
vtable_start_offset
()
*
wordSize
;
...
@@ -1553,15 +1552,18 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -1553,15 +1552,18 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
add
(
scan_temp
,
recv_klass
,
scan_temp
);
add
(
scan_temp
,
recv_klass
,
scan_temp
);
// Adjust recv_klass by scaled itable_index, so we can free itable_index.
// Adjust recv_klass by scaled itable_index, so we can free itable_index.
if
(
itable_index
.
is_register
())
{
if
(
return_method
)
{
Register
itable_offset
=
itable_index
.
as_register
();
if
(
itable_index
.
is_register
())
{
sldi
(
itable_offset
,
itable_offset
,
logMEsize
);
Register
itable_offset
=
itable_index
.
as_register
();
if
(
itentry_off
)
addi
(
itable_offset
,
itable_offset
,
itentry_off
);
sldi
(
method_result
,
itable_offset
,
logMEsize
);
add
(
recv_klass
,
itable_offset
,
recv_klass
);
if
(
itentry_off
)
{
addi
(
method_result
,
method_result
,
itentry_off
);
}
}
else
{
add
(
method_result
,
method_result
,
recv_klass
);
long
itable_offset
=
(
long
)
itable_index
.
as_constant
();
}
else
{
load_const_optimized
(
sethi_temp
,
(
itable_offset
<<
logMEsize
)
+
itentry_off
);
// static address, no relocation
long
itable_offset
=
(
long
)
itable_index
.
as_constant
();
add
(
recv_klass
,
sethi_temp
,
recv_klass
);
// static address, no relocation
load_const_optimized
(
temp2
,
(
itable_offset
<<
logMEsize
)
+
itentry_off
);
// static address, no relocation
add
(
method_result
,
temp2
,
recv_klass
);
}
}
}
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
...
@@ -1574,12 +1576,12 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -1574,12 +1576,12 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
for
(
int
peel
=
1
;
peel
>=
0
;
peel
--
)
{
for
(
int
peel
=
1
;
peel
>=
0
;
peel
--
)
{
// %%%% Could load both offset and interface in one ldx, if they were
// %%%% Could load both offset and interface in one ldx, if they were
// in the opposite order. This would save a load.
// in the opposite order. This would save a load.
ld
(
method_result
,
itableOffsetEntry
::
interface_offset_in_bytes
(),
scan_temp
);
ld
(
temp2
,
itableOffsetEntry
::
interface_offset_in_bytes
(),
scan_temp
);
// Check that this entry is non-null. A null entry means that
// Check that this entry is non-null. A null entry means that
// the receiver class doesn't implement the interface, and wasn't the
// the receiver class doesn't implement the interface, and wasn't the
// same as when the caller was compiled.
// same as when the caller was compiled.
cmpd
(
CCR0
,
method_result
,
intf_klass
);
cmpd
(
CCR0
,
temp2
,
intf_klass
);
if
(
peel
)
{
if
(
peel
)
{
beq
(
CCR0
,
found_method
);
beq
(
CCR0
,
found_method
);
...
@@ -1592,7 +1594,7 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -1592,7 +1594,7 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
bind
(
search
);
bind
(
search
);
cmpdi
(
CCR0
,
method_result
,
0
);
cmpdi
(
CCR0
,
temp2
,
0
);
beq
(
CCR0
,
L_no_such_interface
);
beq
(
CCR0
,
L_no_such_interface
);
addi
(
scan_temp
,
scan_temp
,
scan_step
);
addi
(
scan_temp
,
scan_temp
,
scan_step
);
}
}
...
@@ -1600,9 +1602,11 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -1600,9 +1602,11 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
bind
(
found_method
);
bind
(
found_method
);
// Got a hit.
// Got a hit.
int
ito_offset
=
itableOffsetEntry
::
offset_offset_in_bytes
();
if
(
return_method
)
{
lwz
(
scan_temp
,
ito_offset
,
scan_temp
);
int
ito_offset
=
itableOffsetEntry
::
offset_offset_in_bytes
();
ldx
(
method_result
,
scan_temp
,
recv_klass
);
lwz
(
scan_temp
,
ito_offset
,
scan_temp
);
ldx
(
method_result
,
scan_temp
,
method_result
);
}
}
}
// virtual method calling
// virtual method calling
...
...
src/cpu/ppc/vm/macroAssembler_ppc.hpp
浏览文件 @
e464b779
/*
/*
* Copyright (c) 2002, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 201
4
SAP AG. All rights reserved.
* Copyright 2012, 201
7
SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -441,7 +441,8 @@ class MacroAssembler: public Assembler {
...
@@ -441,7 +441,8 @@ class MacroAssembler: public Assembler {
RegisterOrConstant
itable_index
,
RegisterOrConstant
itable_index
,
Register
method_result
,
Register
method_result
,
Register
temp_reg
,
Register
temp2_reg
,
Register
temp_reg
,
Register
temp2_reg
,
Label
&
no_such_interface
);
Label
&
no_such_interface
,
bool
return_method
=
true
);
// virtual method calling
// virtual method calling
void
lookup_virtual_method
(
Register
recv_klass
,
void
lookup_virtual_method
(
Register
recv_klass
,
...
...
src/cpu/ppc/vm/templateTable_ppc_64.cpp
浏览文件 @
e464b779
/*
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014,
2017
Oracle and/or its affiliates. All rights reserved.
* Copyright 2013, 201
4
SAP AG. All rights reserved.
* Copyright 2013, 201
7
SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -3418,11 +3418,11 @@ void TemplateTable::invokestatic(int byte_no) {
...
@@ -3418,11 +3418,11 @@ void TemplateTable::invokestatic(int byte_no) {
void
TemplateTable
::
invokeinterface_object_method
(
Register
Rrecv_klass
,
void
TemplateTable
::
invokeinterface_object_method
(
Register
Rrecv_klass
,
Register
Rret
,
Register
Rret
,
Register
Rflags
,
Register
Rflags
,
Register
R
index
,
Register
R
method
,
Register
Rtemp1
,
Register
Rtemp1
,
Register
Rtemp2
)
{
Register
Rtemp2
)
{
assert_different_registers
(
R
index
,
Rret
,
Rrecv_klass
,
Rflags
,
Rtemp1
,
Rtemp2
);
assert_different_registers
(
R
method
,
Rret
,
Rrecv_klass
,
Rflags
,
Rtemp1
,
Rtemp2
);
Label
LnotFinal
;
Label
LnotFinal
;
// Check for vfinal.
// Check for vfinal.
...
@@ -3434,14 +3434,14 @@ void TemplateTable::invokeinterface_object_method(Register Rrecv_klass,
...
@@ -3434,14 +3434,14 @@ void TemplateTable::invokeinterface_object_method(Register Rrecv_klass,
// Final call case.
// Final call case.
__
profile_final_call
(
Rtemp1
,
Rscratch
);
__
profile_final_call
(
Rtemp1
,
Rscratch
);
// Argument and return type profiling.
// Argument and return type profiling.
__
profile_arguments_type
(
R
index
,
Rscratch
,
Rrecv_klass
/* scratch */
,
true
);
__
profile_arguments_type
(
R
method
,
Rscratch
,
Rrecv_klass
/* scratch */
,
true
);
// Do the final call - the index (f2) contains the method.
// Do the final call - the index (f2) contains the method.
__
call_from_interpreter
(
R
index
,
Rret
,
Rscratch
,
Rrecv_klass
/* scratch */
);
__
call_from_interpreter
(
R
method
,
Rret
,
Rscratch
,
Rrecv_klass
/* scratch */
);
// Non-final callc case.
// Non-final callc case.
__
bind
(
LnotFinal
);
__
bind
(
LnotFinal
);
__
profile_virtual_call
(
Rrecv_klass
,
Rtemp1
,
Rscratch
,
false
);
__
profile_virtual_call
(
Rrecv_klass
,
Rtemp1
,
Rscratch
,
false
);
generate_vtable_call
(
Rrecv_klass
,
R
index
,
Rret
,
Rscratch
);
generate_vtable_call
(
Rrecv_klass
,
R
method
,
Rret
,
Rscratch
);
}
}
void
TemplateTable
::
invokeinterface
(
int
byte_no
)
{
void
TemplateTable
::
invokeinterface
(
int
byte_no
)
{
...
@@ -3450,58 +3450,61 @@ void TemplateTable::invokeinterface(int byte_no) {
...
@@ -3450,58 +3450,61 @@ void TemplateTable::invokeinterface(int byte_no) {
const
Register
Rscratch1
=
R11_scratch1
,
const
Register
Rscratch1
=
R11_scratch1
,
Rscratch2
=
R12_scratch2
,
Rscratch2
=
R12_scratch2
,
Rscratch3
=
R9_ARG7
,
Rmethod
=
R6_ARG4
,
Rscratch4
=
R10_ARG8
,
Rmethod2
=
R9_ARG7
,
Rtable_addr
=
Rscratch2
,
Rinterface_klass
=
R5_ARG3
,
Rinterface_klass
=
R5_ARG3
,
Rret_type
=
R8_ARG6
,
Rret_addr
=
R8_ARG6
,
Rret_addr
=
Rret_type
,
Rindex
=
R10_ARG8
,
Rindex
=
R6_ARG4
,
Rreceiver
=
R3_ARG1
,
Rreceiver
=
R4_ARG2
,
Rrecv_klass
=
R4_ARG2
,
Rrecv_klass
=
Rreceiver
,
Rflags
=
R7_ARG5
;
Rflags
=
R7_ARG5
;
prepare_invoke
(
byte_no
,
Rinterface_klass
,
Rret_addr
,
R
index
,
Rreceiver
,
Rflags
,
Rscratch1
);
prepare_invoke
(
byte_no
,
Rinterface_klass
,
Rret_addr
,
R
method
,
Rreceiver
,
Rflags
,
Rscratch1
);
// Get receiver klass.
// Get receiver klass.
__
null_check_throw
(
Rreceiver
,
oopDesc
::
klass_offset_in_bytes
(),
Rscratch
3
);
__
null_check_throw
(
Rreceiver
,
oopDesc
::
klass_offset_in_bytes
(),
Rscratch
2
);
__
load_klass
(
Rrecv_klass
,
Rreceiver
);
__
load_klass
(
Rrecv_klass
,
Rreceiver
);
// Check corner case object method.
// Check corner case object method.
Label
LobjectMethod
;
Label
LobjectMethod
,
L_no_such_interface
,
Lthrow_ame
;
__
testbitdi
(
CCR0
,
R0
,
Rflags
,
ConstantPoolCacheEntry
::
is_forced_virtual_shift
);
__
testbitdi
(
CCR0
,
R0
,
Rflags
,
ConstantPoolCacheEntry
::
is_forced_virtual_shift
);
__
btrue
(
CCR0
,
LobjectMethod
);
__
btrue
(
CCR0
,
LobjectMethod
);
// Fallthrough: The normal invokeinterface case.
__
lookup_interface_method
(
Rrecv_klass
,
Rinterface_klass
,
noreg
,
noreg
,
Rscratch1
,
Rscratch2
,
L_no_such_interface
,
/*return_method=*/
false
);
__
profile_virtual_call
(
Rrecv_klass
,
Rscratch1
,
Rscratch2
,
false
);
__
profile_virtual_call
(
Rrecv_klass
,
Rscratch1
,
Rscratch2
,
false
);
// Find entry point to call.
// Find entry point to call.
Label
Lthrow_icc
,
Lthrow_ame
;
// Result will be returned in Rindex.
__
mr
(
Rscratch4
,
Rrecv_klass
);
__
mr
(
Rscratch3
,
Rindex
);
__
lookup_interface_method
(
Rrecv_klass
,
Rinterface_klass
,
Rindex
,
Rindex
,
Rscratch1
,
Rscratch2
,
Lthrow_icc
);
__
cmpdi
(
CCR0
,
Rindex
,
0
);
// Get declaring interface class from method
__
ld
(
Rinterface_klass
,
in_bytes
(
Method
::
const_offset
()),
Rmethod
);
__
ld
(
Rinterface_klass
,
in_bytes
(
ConstMethod
::
constants_offset
()),
Rinterface_klass
);
__
ld
(
Rinterface_klass
,
ConstantPool
::
pool_holder_offset_in_bytes
(),
Rinterface_klass
);
// Get itable index from method
__
lwa
(
Rindex
,
in_bytes
(
Method
::
itable_index_offset
()),
Rmethod
);
__
subfic
(
Rindex
,
Rindex
,
Method
::
itable_index_max
);
__
lookup_interface_method
(
Rrecv_klass
,
Rinterface_klass
,
Rindex
,
Rmethod2
,
Rscratch1
,
Rscratch2
,
L_no_such_interface
);
__
cmpdi
(
CCR0
,
Rmethod2
,
0
);
__
beq
(
CCR0
,
Lthrow_ame
);
__
beq
(
CCR0
,
Lthrow_ame
);
// Found entry. Jump off!
// Found entry. Jump off!
// Argument and return type profiling.
// Argument and return type profiling.
__
profile_arguments_type
(
Rindex
,
Rscratch1
,
Rscratch2
,
true
);
__
profile_arguments_type
(
Rmethod2
,
Rscratch1
,
Rscratch2
,
true
);
__
call_from_interpreter
(
Rindex
,
Rret_addr
,
Rscratch1
,
Rscratch2
);
//__ profile_called_method(Rindex, Rscratch1);
__
call_from_interpreter
(
Rmethod2
,
Rret_addr
,
Rscratch1
,
Rscratch2
);
// Vtable entry was NULL => Throw abstract method error.
// Vtable entry was NULL => Throw abstract method error.
__
bind
(
Lthrow_ame
);
__
bind
(
Lthrow_ame
);
__
mr
(
Rrecv_klass
,
Rscratch4
);
__
mr
(
Rindex
,
Rscratch3
);
call_VM
(
noreg
,
CAST_FROM_FN_PTR
(
address
,
InterpreterRuntime
::
throw_AbstractMethodError
));
call_VM
(
noreg
,
CAST_FROM_FN_PTR
(
address
,
InterpreterRuntime
::
throw_AbstractMethodError
));
// Interface was not found => Throw incompatible class change error.
// Interface was not found => Throw incompatible class change error.
__
bind
(
Lthrow_icc
);
__
bind
(
L_no_such_interface
);
__
mr
(
Rrecv_klass
,
Rscratch4
);
call_VM
(
noreg
,
CAST_FROM_FN_PTR
(
address
,
InterpreterRuntime
::
throw_IncompatibleClassChangeError
));
call_VM
(
noreg
,
CAST_FROM_FN_PTR
(
address
,
InterpreterRuntime
::
throw_IncompatibleClassChangeError
));
DEBUG_ONLY
(
__
should_not_reach_here
();
)
__
should_not_reach_here
();
// Special case of invokeinterface called for virtual method of
// Special case of invokeinterface called for virtual method of
// java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
// java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
...
@@ -3509,7 +3512,7 @@ void TemplateTable::invokeinterface(int byte_no) {
...
@@ -3509,7 +3512,7 @@ void TemplateTable::invokeinterface(int byte_no) {
// to handle this corner case. This code isn't produced by javac, but could
// to handle this corner case. This code isn't produced by javac, but could
// be produced by another compliant java compiler.
// be produced by another compliant java compiler.
__
bind
(
LobjectMethod
);
__
bind
(
LobjectMethod
);
invokeinterface_object_method
(
Rrecv_klass
,
Rret_addr
,
Rflags
,
R
index
,
Rscratch1
,
Rscratch2
);
invokeinterface_object_method
(
Rrecv_klass
,
Rret_addr
,
Rflags
,
R
method
,
Rscratch1
,
Rscratch2
);
}
}
void
TemplateTable
::
invokedynamic
(
int
byte_no
)
{
void
TemplateTable
::
invokedynamic
(
int
byte_no
)
{
...
...
src/cpu/ppc/vm/vtableStubs_ppc_64.cpp
浏览文件 @
e464b779
/*
/*
* Copyright (c) 1997, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 201
4
SAP AG. All rights reserved.
* Copyright 2012, 201
7
SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
#include "code/vtableStubs.hpp"
#include "code/vtableStubs.hpp"
#include "interp_masm_ppc_64.hpp"
#include "interp_masm_ppc_64.hpp"
#include "memory/resourceArea.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/klassVtable.hpp"
#include "oops/klassVtable.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/sharedRuntime.hpp"
...
@@ -56,17 +57,22 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
...
@@ -56,17 +57,22 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
// PPC port: use fixed size.
// PPC port: use fixed size.
const
int
code_length
=
VtableStub
::
pd_code_size_limit
(
true
);
const
int
code_length
=
VtableStub
::
pd_code_size_limit
(
true
);
VtableStub
*
s
=
new
(
code_length
)
VtableStub
(
true
,
vtable_index
);
VtableStub
*
s
=
new
(
code_length
)
VtableStub
(
true
,
vtable_index
);
// Can be NULL if there is no free space in the code cache.
if
(
s
==
NULL
)
{
return
NULL
;
}
ResourceMark
rm
;
ResourceMark
rm
;
CodeBuffer
cb
(
s
->
entry_point
(),
code_length
);
CodeBuffer
cb
(
s
->
entry_point
(),
code_length
);
MacroAssembler
*
masm
=
new
MacroAssembler
(
&
cb
);
MacroAssembler
*
masm
=
new
MacroAssembler
(
&
cb
);
address
start_pc
;
#ifndef PRODUCT
#ifndef PRODUCT
if
(
CountCompiledCalls
)
{
if
(
CountCompiledCalls
)
{
__
load_const
(
R11_scratch1
,
SharedRuntime
::
nof_megamorphic_calls_addr
()
);
int
offs
=
__
load_const_optimized
(
R11_scratch1
,
SharedRuntime
::
nof_megamorphic_calls_addr
(),
R12_scratch2
,
true
);
__
lwz
(
R12_scratch2
,
0
,
R11_scratch1
);
__
lwz
(
R12_scratch2
,
offs
,
R11_scratch1
);
__
addi
(
R12_scratch2
,
R12_scratch2
,
1
);
__
addi
(
R12_scratch2
,
R12_scratch2
,
1
);
__
stw
(
R12_scratch2
,
0
,
R11_scratch1
);
__
stw
(
R12_scratch2
,
offs
,
R11_scratch1
);
}
}
#endif
#endif
...
@@ -116,6 +122,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
...
@@ -116,6 +122,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
__
load_with_trap_null_check
(
R12_scratch2
,
in_bytes
(
Method
::
from_compiled_offset
()),
R19_method
);
__
load_with_trap_null_check
(
R12_scratch2
,
in_bytes
(
Method
::
from_compiled_offset
()),
R19_method
);
__
mtctr
(
R12_scratch2
);
__
mtctr
(
R12_scratch2
);
__
bctr
();
__
bctr
();
masm
->
flush
();
masm
->
flush
();
guarantee
(
__
pc
()
<=
s
->
code_end
(),
"overflowed buffer"
);
guarantee
(
__
pc
()
<=
s
->
code_end
(),
"overflowed buffer"
);
...
@@ -125,10 +132,16 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
...
@@ -125,10 +132,16 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
return
s
;
return
s
;
}
}
VtableStub
*
VtableStubs
::
create_itable_stub
(
int
v
table_index
)
{
VtableStub
*
VtableStubs
::
create_itable_stub
(
int
i
table_index
)
{
// PPC port: use fixed size.
// PPC port: use fixed size.
const
int
code_length
=
VtableStub
::
pd_code_size_limit
(
false
);
const
int
code_length
=
VtableStub
::
pd_code_size_limit
(
false
);
VtableStub
*
s
=
new
(
code_length
)
VtableStub
(
false
,
vtable_index
);
VtableStub
*
s
=
new
(
code_length
)
VtableStub
(
false
,
itable_index
);
// Can be NULL if there is no free space in the code cache.
if
(
s
==
NULL
)
{
return
NULL
;
}
ResourceMark
rm
;
ResourceMark
rm
;
CodeBuffer
cb
(
s
->
entry_point
(),
code_length
);
CodeBuffer
cb
(
s
->
entry_point
(),
code_length
);
MacroAssembler
*
masm
=
new
MacroAssembler
(
&
cb
);
MacroAssembler
*
masm
=
new
MacroAssembler
(
&
cb
);
...
@@ -136,10 +149,10 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
...
@@ -136,10 +149,10 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
#ifndef PRODUCT
#ifndef PRODUCT
if
(
CountCompiledCalls
)
{
if
(
CountCompiledCalls
)
{
__
load_const
(
R11_scratch1
,
SharedRuntime
::
nof_megamorphic_calls_addr
()
);
int
offs
=
__
load_const_optimized
(
R11_scratch1
,
SharedRuntime
::
nof_megamorphic_calls_addr
(),
R12_scratch2
,
true
);
__
lwz
(
R12_scratch2
,
0
,
R11_scratch1
);
__
lwz
(
R12_scratch2
,
offs
,
R11_scratch1
);
__
addi
(
R12_scratch2
,
R12_scratch2
,
1
);
__
addi
(
R12_scratch2
,
R12_scratch2
,
1
);
__
stw
(
R12_scratch2
,
0
,
R11_scratch1
);
__
stw
(
R12_scratch2
,
offs
,
R11_scratch1
);
}
}
#endif
#endif
...
@@ -148,61 +161,27 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
...
@@ -148,61 +161,27 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
// Entry arguments:
// Entry arguments:
// R19_method: Interface
// R19_method: Interface
// R3_ARG1: Receiver
// R3_ARG1: Receiver
//
const
Register
rcvr_klass
=
R11_scratch1
;
const
Register
vtable_len
=
R12_scratch2
;
const
Register
itable_entry_addr
=
R21_tmp1
;
const
Register
itable_interface
=
R22_tmp2
;
// Get receiver klass.
Label
L_no_such_interface
;
const
Register
rcvr_klass
=
R11_scratch1
,
interface
=
R12_scratch2
,
tmp1
=
R21_tmp1
,
tmp2
=
R22_tmp2
;
// We might implicit NULL fault here.
address
npe_addr
=
__
pc
();
// npe = null pointer exception
address
npe_addr
=
__
pc
();
// npe = null pointer exception
__
load_klass_with_trap_null_check
(
rcvr_klass
,
R3_ARG1
);
__
load_klass_with_trap_null_check
(
rcvr_klass
,
R3_ARG1
);
BLOCK_COMMENT
(
"Load start of itable entries into itable_entry."
);
// Receiver subtype check against REFC.
__
lwz
(
vtable_len
,
InstanceKlass
::
vtable_length_offset
()
*
wordSize
,
rcvr_klass
);
__
ld
(
interface
,
CompiledICHolder
::
holder_klass_offset
(),
R19_method
);
__
slwi
(
vtable_len
,
vtable_len
,
exact_log2
(
vtableEntry
::
size
()
*
wordSize
));
__
lookup_interface_method
(
rcvr_klass
,
interface
,
noreg
,
__
add
(
itable_entry_addr
,
vtable_len
,
rcvr_klass
);
R0
,
tmp1
,
tmp2
,
L_no_such_interface
,
/*return_method=*/
false
);
// Loop over all itable entries until desired interfaceOop(Rinterface) found.
BLOCK_COMMENT
(
"Increment itable_entry_addr in loop."
);
const
int
vtable_base_offset
=
InstanceKlass
::
vtable_start_offset
()
*
wordSize
;
__
addi
(
itable_entry_addr
,
itable_entry_addr
,
vtable_base_offset
+
itableOffsetEntry
::
interface_offset_in_bytes
());
const
int
itable_offset_search_inc
=
itableOffsetEntry
::
size
()
*
wordSize
;
// Get Method* and entrypoint for compiler
Label
search
;
__
ld
(
interface
,
CompiledICHolder
::
holder_metadata_offset
(),
R19_method
);
__
bind
(
search
);
__
lookup_interface_method
(
rcvr_klass
,
interface
,
itable_index
,
__
ld
(
itable_interface
,
0
,
itable_entry_addr
);
R19_method
,
tmp1
,
tmp2
,
L_no_such_interface
,
/*return_method=*/
true
);
// Handle IncompatibleClassChangeError in itable stubs.
// If the entry is NULL then we've reached the end of the table
// without finding the expected interface, so throw an exception.
BLOCK_COMMENT
(
"Handle IncompatibleClassChangeError in itable stubs."
);
Label
throw_icce
;
__
cmpdi
(
CCR1
,
itable_interface
,
0
);
__
cmpd
(
CCR0
,
itable_interface
,
R19_method
);
__
addi
(
itable_entry_addr
,
itable_entry_addr
,
itable_offset_search_inc
);
__
beq
(
CCR1
,
throw_icce
);
__
bne
(
CCR0
,
search
);
// Entry found and itable_entry_addr points to it, get offset of vtable for interface.
const
Register
vtable_offset
=
R12_scratch2
;
const
Register
itable_method
=
R11_scratch1
;
const
int
vtable_offset_offset
=
(
itableOffsetEntry
::
offset_offset_in_bytes
()
-
itableOffsetEntry
::
interface_offset_in_bytes
())
-
itable_offset_search_inc
;
__
lwz
(
vtable_offset
,
vtable_offset_offset
,
itable_entry_addr
);
// Compute itableMethodEntry and get method and entry point for compiler.
const
int
method_offset
=
(
itableMethodEntry
::
size
()
*
wordSize
*
vtable_index
)
+
itableMethodEntry
::
method_offset_in_bytes
();
__
add
(
itable_method
,
rcvr_klass
,
vtable_offset
);
__
ld
(
R19_method
,
method_offset
,
itable_method
);
#ifndef PRODUCT
#ifndef PRODUCT
if
(
DebugVtables
)
{
if
(
DebugVtables
)
{
...
@@ -224,7 +203,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
...
@@ -224,7 +203,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
__
trap_null_check
(
R19_method
);
__
trap_null_check
(
R19_method
);
}
else
{
}
else
{
__
cmpdi
(
CCR0
,
R19_method
,
0
);
__
cmpdi
(
CCR0
,
R19_method
,
0
);
__
beq
(
CCR0
,
throw_ic
ce
);
__
beq
(
CCR0
,
L_no_such_interfa
ce
);
}
}
}
}
__
ld
(
R12_scratch2
,
in_bytes
(
Method
::
from_compiled_offset
()),
R19_method
);
__
ld
(
R12_scratch2
,
in_bytes
(
Method
::
from_compiled_offset
()),
R19_method
);
...
@@ -236,8 +215,8 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
...
@@ -236,8 +215,8 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
// We force resolving of the call site by jumping to the "handle
// We force resolving of the call site by jumping to the "handle
// wrong method" stub, and so let the interpreter runtime do all the
// wrong method" stub, and so let the interpreter runtime do all the
// dirty work.
// dirty work.
__
bind
(
throw_ic
ce
);
__
bind
(
L_no_such_interfa
ce
);
__
load_const
(
R11_scratch1
,
SharedRuntime
::
get_handle_wrong_method_stub
()
);
__
load_const
_optimized
(
R11_scratch1
,
SharedRuntime
::
get_handle_wrong_method_stub
(),
R12_scratch2
);
__
mtctr
(
R11_scratch1
);
__
mtctr
(
R11_scratch1
);
__
bctr
();
__
bctr
();
...
@@ -252,14 +231,15 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
...
@@ -252,14 +231,15 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
int
VtableStub
::
pd_code_size_limit
(
bool
is_vtable_stub
)
{
int
VtableStub
::
pd_code_size_limit
(
bool
is_vtable_stub
)
{
if
(
TraceJumps
||
DebugVtables
||
CountCompiledCalls
||
VerifyOops
)
{
if
(
TraceJumps
||
DebugVtables
||
CountCompiledCalls
||
VerifyOops
)
{
return
1000
;
return
1000
;
}
else
{
int
decode_klass_size
=
MacroAssembler
::
instr_size_for_decode_klass_not_null
();
if
(
is_vtable_stub
)
{
return
20
+
decode_klass_size
+
8
+
8
;
// Plain + cOops + Traps + safety
}
else
{
return
96
+
decode_klass_size
+
12
+
8
;
// Plain + cOops + Traps + safety
}
}
}
int
size
=
is_vtable_stub
?
20
+
8
:
164
+
20
;
// Plain + safety
if
(
UseCompressedClassPointers
)
{
size
+=
MacroAssembler
::
instr_size_for_decode_klass_not_null
();
}
if
(
!
ImplicitNullChecks
||
!
os
::
zero_page_read_protected
())
{
size
+=
is_vtable_stub
?
8
:
12
;
}
return
size
;
}
}
int
VtableStub
::
pd_code_alignment
()
{
int
VtableStub
::
pd_code_alignment
()
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录