Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
21b5cc64
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看板
提交
21b5cc64
编写于
9月 29, 2017
作者:
D
dbuck
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8174962: Better interface invocations
Reviewed-by: jrose, coleenp, ahgross, acorn, vlivanov
上级
6bcabbbc
变更
27
隐藏空白更改
内联
并排
Showing
27 changed file
with
426 addition
and
239 deletion
+426
-239
agent/src/share/classes/sun/jvm/hotspot/oops/CompiledICHolder.java
.../share/classes/sun/jvm/hotspot/oops/CompiledICHolder.java
+8
-8
src/cpu/ppc/vm/sharedRuntime_ppc.cpp
src/cpu/ppc/vm/sharedRuntime_ppc.cpp
+2
-2
src/cpu/sparc/vm/macroAssembler_sparc.cpp
src/cpu/sparc/vm/macroAssembler_sparc.cpp
+19
-14
src/cpu/sparc/vm/macroAssembler_sparc.hpp
src/cpu/sparc/vm/macroAssembler_sparc.hpp
+3
-2
src/cpu/sparc/vm/sharedRuntime_sparc.cpp
src/cpu/sparc/vm/sharedRuntime_sparc.cpp
+2
-2
src/cpu/sparc/vm/templateTable_sparc.cpp
src/cpu/sparc/vm/templateTable_sparc.cpp
+33
-47
src/cpu/sparc/vm/vtableStubs_sparc.cpp
src/cpu/sparc/vm/vtableStubs_sparc.cpp
+21
-7
src/cpu/x86/vm/macroAssembler_x86.cpp
src/cpu/x86/vm/macroAssembler_x86.cpp
+18
-9
src/cpu/x86/vm/macroAssembler_x86.hpp
src/cpu/x86/vm/macroAssembler_x86.hpp
+3
-2
src/cpu/x86/vm/sharedRuntime_x86_32.cpp
src/cpu/x86/vm/sharedRuntime_x86_32.cpp
+2
-2
src/cpu/x86/vm/sharedRuntime_x86_64.cpp
src/cpu/x86/vm/sharedRuntime_x86_64.cpp
+2
-2
src/cpu/x86/vm/templateTable_x86_32.cpp
src/cpu/x86/vm/templateTable_x86_32.cpp
+24
-5
src/cpu/x86/vm/templateTable_x86_64.cpp
src/cpu/x86/vm/templateTable_x86_64.cpp
+23
-5
src/cpu/x86/vm/vtableStubs_x86_32.cpp
src/cpu/x86/vm/vtableStubs_x86_32.cpp
+36
-17
src/cpu/x86/vm/vtableStubs_x86_64.cpp
src/cpu/x86/vm/vtableStubs_x86_64.cpp
+37
-22
src/share/vm/code/compiledIC.cpp
src/share/vm/code/compiledIC.cpp
+14
-4
src/share/vm/code/compiledIC.hpp
src/share/vm/code/compiledIC.hpp
+4
-4
src/share/vm/code/nmethod.cpp
src/share/vm/code/nmethod.cpp
+3
-4
src/share/vm/interpreter/interpreterRuntime.cpp
src/share/vm/interpreter/interpreterRuntime.cpp
+1
-0
src/share/vm/oops/compiledICHolder.cpp
src/share/vm/oops/compiledICHolder.cpp
+20
-4
src/share/vm/oops/compiledICHolder.hpp
src/share/vm/oops/compiledICHolder.hpp
+13
-11
src/share/vm/oops/cpCache.cpp
src/share/vm/oops/cpCache.cpp
+44
-59
src/share/vm/oops/cpCache.hpp
src/share/vm/oops/cpCache.hpp
+4
-2
src/share/vm/oops/klassVtable.cpp
src/share/vm/oops/klassVtable.cpp
+4
-3
src/share/vm/oops/method.hpp
src/share/vm/oops/method.hpp
+2
-1
src/share/vm/runtime/vmStructs.cpp
src/share/vm/runtime/vmStructs.cpp
+1
-1
test/runtime/RedefineTests/RedefineInterfaceCall.java
test/runtime/RedefineTests/RedefineInterfaceCall.java
+83
-0
未找到文件。
agent/src/share/classes/sun/jvm/hotspot/oops/CompiledICHolder.java
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 2000, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
7
, Oracle and/or its affiliates. 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
...
@@ -40,10 +40,10 @@ public class CompiledICHolder extends VMObject {
...
@@ -40,10 +40,10 @@ public class CompiledICHolder extends VMObject {
}
}
private
static
synchronized
void
initialize
(
TypeDataBase
db
)
throws
WrongTypeException
{
private
static
synchronized
void
initialize
(
TypeDataBase
db
)
throws
WrongTypeException
{
Type
type
=
db
.
lookupType
(
"CompiledICHolder"
);
Type
type
=
db
.
lookupType
(
"CompiledICHolder"
);
holderMet
hod
=
new
MetadataField
(
type
.
getAddressField
(
"_holder_method
"
),
0
);
holderMet
adata
=
new
MetadataField
(
type
.
getAddressField
(
"_holder_metadata
"
),
0
);
holderKlass
=
new
MetadataField
(
type
.
getAddressField
(
"_holder_klass"
),
0
);
holderKlass
=
new
MetadataField
(
type
.
getAddressField
(
"_holder_klass"
),
0
);
headerSize
=
type
.
getSize
();
headerSize
=
type
.
getSize
();
}
}
public
CompiledICHolder
(
Address
addr
)
{
public
CompiledICHolder
(
Address
addr
)
{
...
@@ -55,12 +55,12 @@ public class CompiledICHolder extends VMObject {
...
@@ -55,12 +55,12 @@ public class CompiledICHolder extends VMObject {
private
static
long
headerSize
;
private
static
long
headerSize
;
// Fields
// Fields
private
static
MetadataField
holderMet
hod
;
private
static
MetadataField
holderMet
adata
;
private
static
MetadataField
holderKlass
;
private
static
MetadataField
holderKlass
;
// Accessors for declared fields
// Accessors for declared fields
public
Met
hod
getHolderMethod
()
{
return
(
Method
)
holderMethod
.
getValue
(
this
);
}
public
Met
adata
getHolderMetadata
()
{
return
(
Metadata
)
holderMetadata
.
getValue
(
this
);
}
public
Klass
getHolderKlass
()
{
return
(
Klass
)
holderKlass
.
getValue
(
this
);
}
public
Klass
getHolderKlass
()
{
return
(
Klass
)
holderKlass
.
getValue
(
this
);
}
public
void
printValueOn
(
PrintStream
tty
)
{
public
void
printValueOn
(
PrintStream
tty
)
{
tty
.
print
(
"CompiledICHolder"
);
tty
.
print
(
"CompiledICHolder"
);
...
...
src/cpu/ppc/vm/sharedRuntime_ppc.cpp
浏览文件 @
21b5cc64
/*
/*
* 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, 2014 SAP AG. All rights reserved.
* Copyright 2012, 2014 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.
*
*
...
@@ -1193,7 +1193,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
...
@@ -1193,7 +1193,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
// Argument is valid and klass is as expected, continue.
// Argument is valid and klass is as expected, continue.
// Extract method from inline cache, verified entry point needs it.
// Extract method from inline cache, verified entry point needs it.
__
ld
(
R19_method
,
CompiledICHolder
::
holder_met
hod
_offset
(),
ic
);
__
ld
(
R19_method
,
CompiledICHolder
::
holder_met
adata
_offset
(),
ic
);
assert
(
R19_method
==
ic
,
"the inline cache register is dead here"
);
assert
(
R19_method
==
ic
,
"the inline cache register is dead here"
);
__
ld
(
code
,
method_
(
code
));
__
ld
(
code
,
method_
(
code
));
...
...
src/cpu/sparc/vm/macroAssembler_sparc.cpp
浏览文件 @
21b5cc64
/*
/*
* 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.
* 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
...
@@ -2183,9 +2183,10 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -2183,9 +2183,10 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
Register
method_result
,
Register
method_result
,
Register
scan_temp
,
Register
scan_temp
,
Register
sethi_temp
,
Register
sethi_temp
,
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
,
assert
(
!
return_method
||
itable_index
.
is_constant
()
||
itable_index
.
as_register
()
==
method_result
,
"caller must use same register for non-constant itable index as for method"
);
"caller must use same register for non-constant itable index as for method"
);
Label
L_no_such_interface_restore
;
Label
L_no_such_interface_restore
;
...
@@ -2229,11 +2230,13 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -2229,11 +2230,13 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
}
}
add
(
recv_klass
,
scan_temp
,
scan_temp
);
add
(
recv_klass
,
scan_temp
,
scan_temp
);
// Adjust recv_klass by scaled itable_index, so we can free itable_index.
if
(
return_method
)
{
RegisterOrConstant
itable_offset
=
itable_index
;
// Adjust recv_klass by scaled itable_index, so we can free itable_index.
itable_offset
=
regcon_sll_ptr
(
itable_index
,
exact_log2
(
itableMethodEntry
::
size
()
*
wordSize
),
itable_offset
);
RegisterOrConstant
itable_offset
=
itable_index
;
itable_offset
=
regcon_inc_ptr
(
itable_offset
,
itableMethodEntry
::
method_offset_in_bytes
(),
itable_offset
);
itable_offset
=
regcon_sll_ptr
(
itable_index
,
exact_log2
(
itableMethodEntry
::
size
()
*
wordSize
),
itable_offset
);
add
(
recv_klass
,
ensure_simm13_or_reg
(
itable_offset
,
sethi_temp
),
recv_klass
);
itable_offset
=
regcon_inc_ptr
(
itable_offset
,
itableMethodEntry
::
method_offset_in_bytes
(),
itable_offset
);
add
(
recv_klass
,
ensure_simm13_or_reg
(
itable_offset
,
sethi_temp
),
recv_klass
);
}
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
// if (scan->interface() == intf) {
// if (scan->interface() == intf) {
...
@@ -2268,12 +2271,14 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -2268,12 +2271,14 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
bind
(
L_found_method
);
bind
(
L_found_method
);
// Got a hit.
if
(
return_method
)
{
int
ito_offset
=
itableOffsetEntry
::
offset_offset_in_bytes
();
// Got a hit.
// scan_temp[-scan_step] points to the vtable offset we need
int
ito_offset
=
itableOffsetEntry
::
offset_offset_in_bytes
();
ito_offset
-=
scan_step
;
// scan_temp[-scan_step] points to the vtable offset we need
lduw
(
scan_temp
,
ito_offset
,
scan_temp
);
ito_offset
-=
scan_step
;
ld_ptr
(
recv_klass
,
scan_temp
,
method_result
);
lduw
(
scan_temp
,
ito_offset
,
scan_temp
);
ld_ptr
(
recv_klass
,
scan_temp
,
method_result
);
}
if
(
did_save
)
{
if
(
did_save
)
{
Label
L_done
;
Label
L_done
;
...
...
src/cpu/sparc/vm/macroAssembler_sparc.hpp
浏览文件 @
21b5cc64
/*
/*
* 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.
* 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
...
@@ -1347,7 +1347,8 @@ public:
...
@@ -1347,7 +1347,8 @@ public:
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/sparc/vm/sharedRuntime_sparc.cpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
7
, Oracle and/or its affiliates. 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
...
@@ -1045,7 +1045,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
...
@@ -1045,7 +1045,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
Label
ok
,
ok2
;
Label
ok
,
ok2
;
__
brx
(
Assembler
::
equal
,
false
,
Assembler
::
pt
,
ok
);
__
brx
(
Assembler
::
equal
,
false
,
Assembler
::
pt
,
ok
);
__
delayed
()
->
ld_ptr
(
G5_method
,
CompiledICHolder
::
holder_met
hod
_offset
(),
G5_method
);
__
delayed
()
->
ld_ptr
(
G5_method
,
CompiledICHolder
::
holder_met
adata
_offset
(),
G5_method
);
__
jump_to
(
ic_miss
,
G3_scratch
);
__
jump_to
(
ic_miss
,
G3_scratch
);
__
delayed
()
->
nop
();
__
delayed
()
->
nop
();
...
...
src/cpu/sparc/vm/templateTable_sparc.cpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. 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
...
@@ -3165,15 +3165,15 @@ void TemplateTable::invokeinterface(int byte_no) {
...
@@ -3165,15 +3165,15 @@ void TemplateTable::invokeinterface(int byte_no) {
assert
(
byte_no
==
f1_byte
,
"use this argument"
);
assert
(
byte_no
==
f1_byte
,
"use this argument"
);
const
Register
Rinterface
=
G1_scratch
;
const
Register
Rinterface
=
G1_scratch
;
const
Register
Rmethod
=
Lscratch
;
const
Register
Rret
=
G3_scratch
;
const
Register
Rret
=
G3_scratch
;
const
Register
Rindex
=
Lscratch
;
const
Register
O0_recv
=
O0
;
const
Register
O0_recv
=
O0
;
const
Register
O1_flags
=
O1
;
const
Register
O1_flags
=
O1
;
const
Register
O2_Klass
=
O2
;
const
Register
O2_Klass
=
O2
;
const
Register
Rscratch
=
G4_scratch
;
const
Register
Rscratch
=
G4_scratch
;
assert_different_registers
(
Rscratch
,
G5_method
);
assert_different_registers
(
Rscratch
,
G5_method
);
prepare_invoke
(
byte_no
,
Rinterface
,
Rret
,
R
index
,
O0_recv
,
O1_flags
);
prepare_invoke
(
byte_no
,
Rinterface
,
Rret
,
R
method
,
O0_recv
,
O1_flags
);
// get receiver klass
// get receiver klass
__
null_check
(
O0_recv
,
oopDesc
::
klass_offset_in_bytes
());
__
null_check
(
O0_recv
,
oopDesc
::
klass_offset_in_bytes
());
...
@@ -3193,58 +3193,40 @@ void TemplateTable::invokeinterface(int byte_no) {
...
@@ -3193,58 +3193,40 @@ void TemplateTable::invokeinterface(int byte_no) {
__
bind
(
notMethod
);
__
bind
(
notMethod
);
__
profile_virtual_call
(
O2_Klass
,
O4
);
//
// find entry point to call
//
// compute start of first itableOffsetEntry (which is at end of vtable)
const
int
base
=
InstanceKlass
::
vtable_start_offset
()
*
wordSize
;
Label
search
;
Register
Rtemp
=
O1_flags
;
Register
Rtemp
=
O1_flags
;
__
ld
(
O2_Klass
,
InstanceKlass
::
vtable_length_offset
()
*
wordSize
,
Rtemp
);
Label
L_no_such_interface
;
if
(
align_object_offset
(
1
)
>
1
)
{
__
round_to
(
Rtemp
,
align_object_offset
(
1
));
}
__
sll
(
Rtemp
,
LogBytesPerWord
,
Rtemp
);
// Rscratch *= 4;
if
(
Assembler
::
is_simm13
(
base
))
{
__
add
(
Rtemp
,
base
,
Rtemp
);
}
else
{
__
set
(
base
,
Rscratch
);
__
add
(
Rscratch
,
Rtemp
,
Rtemp
);
}
__
add
(
O2_Klass
,
Rtemp
,
Rscratch
);
__
bind
(
search
);
// Receiver subtype check against REFC.
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
O2_Klass
,
Rinterface
,
noreg
,
// outputs: temp reg1, temp reg2, temp reg3
G5_method
,
Rscratch
,
Rtemp
,
L_no_such_interface
,
/*return_method=*/
false
);
__
ld_ptr
(
Rscratch
,
itableOffsetEntry
::
interface_offset_in_bytes
(),
Rtemp
);
__
profile_virtual_call
(
O2_Klass
,
O4
);
{
Label
ok
;
// Check that entry is non-null. Null entries are probably a bytecode
//
// problem. If the interface isn't implemented by the receiver class,
// find entry point to call
// the VM should throw IncompatibleClassChangeError. linkResolver checks
//
// this too but that's only if the entry isn't already resolved, so we
// need to check again.
__
br_notnull_short
(
Rtemp
,
Assembler
::
pt
,
ok
);
call_VM
(
noreg
,
CAST_FROM_FN_PTR
(
address
,
InterpreterRuntime
::
throw_IncompatibleClassChangeError
));
__
should_not_reach_here
();
__
bind
(
ok
);
}
__
cmp
(
Rinterface
,
Rtemp
);
// Get declaring interface class from method
__
brx
(
Assembler
::
notEqual
,
true
,
Assembler
::
pn
,
search
);
__
ld_ptr
(
Rmethod
,
Method
::
const_offset
(),
Rinterface
);
__
delayed
()
->
add
(
Rscratch
,
itableOffsetEntry
::
size
()
*
wordSize
,
Rscratch
);
__
ld_ptr
(
Rinterface
,
ConstMethod
::
constants_offset
(),
Rinterface
);
__
ld_ptr
(
Rinterface
,
ConstantPool
::
pool_holder_offset_in_bytes
(),
Rinterface
);
// entry found and Rscratch points to it
// Get itable index from method
__
ld
(
Rscratch
,
itableOffsetEntry
::
offset_offset_in_bytes
(),
Rscratch
);
const
Register
Rindex
=
G5_method
;
__
ld
(
Rmethod
,
Method
::
itable_index_offset
(),
Rindex
);
__
sub
(
Rindex
,
Method
::
itable_index_max
,
Rindex
);
__
neg
(
Rindex
);
assert
(
itableMethodEntry
::
method_offset_in_bytes
()
==
0
,
"adjust instruction below"
);
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
__
sll
(
Rindex
,
exact_log2
(
itableMethodEntry
::
size
()
*
wordSize
),
Rindex
);
// Rindex *= 8;
O2_Klass
,
Rinterface
,
Rindex
,
__
add
(
Rscratch
,
Rindex
,
Rscratch
);
// outputs: method, scan temp reg, temp reg
__
ld_ptr
(
O2_Klass
,
Rscratch
,
G5_method
);
G5_method
,
Rscratch
,
Rtemp
,
L_no_such_interface
);
// Check for abstract method error.
// Check for abstract method error.
{
{
...
@@ -3260,6 +3242,10 @@ void TemplateTable::invokeinterface(int byte_no) {
...
@@ -3260,6 +3242,10 @@ void TemplateTable::invokeinterface(int byte_no) {
__
profile_arguments_type
(
G5_method
,
Rcall
,
Gargs
,
true
);
__
profile_arguments_type
(
G5_method
,
Rcall
,
Gargs
,
true
);
__
call_from_interpreter
(
Rcall
,
Gargs
,
Rret
);
__
call_from_interpreter
(
Rcall
,
Gargs
,
Rret
);
__
bind
(
L_no_such_interface
);
call_VM
(
noreg
,
CAST_FROM_FN_PTR
(
address
,
InterpreterRuntime
::
throw_IncompatibleClassChangeError
));
__
should_not_reach_here
();
}
}
void
TemplateTable
::
invokehandle
(
int
byte_no
)
{
void
TemplateTable
::
invokehandle
(
int
byte_no
)
{
...
...
src/cpu/sparc/vm/vtableStubs_sparc.cpp
浏览文件 @
21b5cc64
/*
/*
* 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.
* 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
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include "code/vtableStubs.hpp"
#include "code/vtableStubs.hpp"
#include "interp_masm_sparc.hpp"
#include "interp_masm_sparc.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"
...
@@ -140,7 +141,8 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
...
@@ -140,7 +141,8 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
MacroAssembler
*
masm
=
new
MacroAssembler
(
&
cb
);
MacroAssembler
*
masm
=
new
MacroAssembler
(
&
cb
);
Register
G3_Klass
=
G3_scratch
;
Register
G3_Klass
=
G3_scratch
;
Register
G5_interface
=
G5
;
// Passed in as an argument
Register
G5_icholder
=
G5
;
// Passed in as an argument
Register
G4_interface
=
G4_scratch
;
Label
search
;
Label
search
;
// Entry arguments:
// Entry arguments:
...
@@ -164,14 +166,26 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
...
@@ -164,14 +166,26 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
}
}
#endif
/* PRODUCT */
#endif
/* PRODUCT */
Label
throw_ic
ce
;
Label
L_no_such_interfa
ce
;
Register
L5_method
=
L5
;
Register
L5_method
=
L5
;
// Receiver subtype check against REFC.
__
ld_ptr
(
G5_icholder
,
CompiledICHolder
::
holder_klass_offset
(),
G4_interface
);
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
G3_Klass
,
G4_interface
,
itable_index
,
// outputs: scan temp. reg1, scan temp. reg2
L5_method
,
L2
,
L3
,
L_no_such_interface
,
/*return_method=*/
false
);
// Get Method* and entrypoint for compiler
__
ld_ptr
(
G5_icholder
,
CompiledICHolder
::
holder_metadata_offset
(),
G4_interface
);
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
G3_Klass
,
G
5
_interface
,
itable_index
,
G3_Klass
,
G
4
_interface
,
itable_index
,
// outputs: method, scan temp. reg
// outputs: method, scan temp. reg
L5_method
,
L2
,
L3
,
L5_method
,
L2
,
L3
,
throw_ic
ce
);
L_no_such_interfa
ce
);
#ifndef PRODUCT
#ifndef PRODUCT
if
(
DebugVtables
)
{
if
(
DebugVtables
)
{
...
@@ -197,7 +211,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
...
@@ -197,7 +211,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
__
JMP
(
G3_scratch
,
0
);
__
JMP
(
G3_scratch
,
0
);
__
delayed
()
->
nop
();
__
delayed
()
->
nop
();
__
bind
(
throw_ic
ce
);
__
bind
(
L_no_such_interfa
ce
);
AddressLiteral
icce
(
StubRoutines
::
throw_IncompatibleClassChangeError_entry
());
AddressLiteral
icce
(
StubRoutines
::
throw_IncompatibleClassChangeError_entry
());
__
jump_to
(
icce
,
G3_scratch
);
__
jump_to
(
icce
,
G3_scratch
);
__
delayed
()
->
restore
();
__
delayed
()
->
restore
();
...
@@ -232,7 +246,7 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
...
@@ -232,7 +246,7 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
MacroAssembler
::
instr_size_for_decode_klass_not_null
()
:
0
);
MacroAssembler
::
instr_size_for_decode_klass_not_null
()
:
0
);
return
basic
+
slop
;
return
basic
+
slop
;
}
else
{
}
else
{
const
int
basic
=
(
2
8
LP64_ONLY
(
+
6
))
*
BytesPerInstWord
+
const
int
basic
=
(
4
8
LP64_ONLY
(
+
6
))
*
BytesPerInstWord
+
// shift;add for load_klass (only shift with zero heap based)
// shift;add for load_klass (only shift with zero heap based)
(
UseCompressedClassPointers
?
(
UseCompressedClassPointers
?
MacroAssembler
::
instr_size_for_decode_klass_not_null
()
:
0
);
MacroAssembler
::
instr_size_for_decode_klass_not_null
()
:
0
);
...
...
src/cpu/x86/vm/macroAssembler_x86.cpp
浏览文件 @
21b5cc64
/*
/*
* 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.
* 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
...
@@ -4853,8 +4853,13 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -4853,8 +4853,13 @@ 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
,
Label
&
L_no_such_interface
)
{
Label
&
L_no_such_interface
,
assert_different_registers
(
recv_klass
,
intf_klass
,
method_result
,
scan_temp
);
bool
return_method
)
{
assert_different_registers
(
recv_klass
,
intf_klass
,
scan_temp
);
assert_different_registers
(
method_result
,
intf_klass
,
scan_temp
);
assert
(
recv_klass
!=
method_result
||
!
return_method
,
"recv_klass can be destroyed when method isn't needed"
);
assert
(
itable_index
.
is_constant
()
||
itable_index
.
as_register
()
==
method_result
,
assert
(
itable_index
.
is_constant
()
||
itable_index
.
as_register
()
==
method_result
,
"caller must use same register for non-constant itable index as for method"
);
"caller must use same register for non-constant itable index as for method"
);
...
@@ -4876,9 +4881,11 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -4876,9 +4881,11 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
round_to
(
scan_temp
,
BytesPerLong
);
round_to
(
scan_temp
,
BytesPerLong
);
}
}
// Adjust recv_klass by scaled itable_index, so we can free itable_index.
if
(
return_method
)
{
assert
(
itableMethodEntry
::
size
()
*
wordSize
==
wordSize
,
"adjust the scaling in the code below"
);
// Adjust recv_klass by scaled itable_index, so we can free itable_index.
lea
(
recv_klass
,
Address
(
recv_klass
,
itable_index
,
Address
::
times_ptr
,
itentry_off
));
assert
(
itableMethodEntry
::
size
()
*
wordSize
==
wordSize
,
"adjust the scaling in the code below"
);
lea
(
recv_klass
,
Address
(
recv_klass
,
itable_index
,
Address
::
times_ptr
,
itentry_off
));
}
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
// if (scan->interface() == intf) {
// if (scan->interface() == intf) {
...
@@ -4912,9 +4919,11 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
...
@@ -4912,9 +4919,11 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
bind
(
found_method
);
bind
(
found_method
);
// Got a hit.
if
(
return_method
)
{
movl
(
scan_temp
,
Address
(
scan_temp
,
itableOffsetEntry
::
offset_offset_in_bytes
()));
// Got a hit.
movptr
(
method_result
,
Address
(
recv_klass
,
scan_temp
,
Address
::
times_1
));
movl
(
scan_temp
,
Address
(
scan_temp
,
itableOffsetEntry
::
offset_offset_in_bytes
()));
movptr
(
method_result
,
Address
(
recv_klass
,
scan_temp
,
Address
::
times_1
));
}
}
}
...
...
src/cpu/x86/vm/macroAssembler_x86.hpp
浏览文件 @
21b5cc64
/*
/*
* 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.
* 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
...
@@ -525,7 +525,8 @@ class MacroAssembler: public Assembler {
...
@@ -525,7 +525,8 @@ class MacroAssembler: public Assembler {
RegisterOrConstant
itable_index
,
RegisterOrConstant
itable_index
,
Register
method_result
,
Register
method_result
,
Register
scan_temp
,
Register
scan_temp
,
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/x86/vm/sharedRuntime_x86_32.cpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
7
, Oracle and/or its affiliates. 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
...
@@ -955,7 +955,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
...
@@ -955,7 +955,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
Label
missed
;
Label
missed
;
__
movptr
(
temp
,
Address
(
receiver
,
oopDesc
::
klass_offset_in_bytes
()));
__
movptr
(
temp
,
Address
(
receiver
,
oopDesc
::
klass_offset_in_bytes
()));
__
cmpptr
(
temp
,
Address
(
holder
,
CompiledICHolder
::
holder_klass_offset
()));
__
cmpptr
(
temp
,
Address
(
holder
,
CompiledICHolder
::
holder_klass_offset
()));
__
movptr
(
rbx
,
Address
(
holder
,
CompiledICHolder
::
holder_met
hod
_offset
()));
__
movptr
(
rbx
,
Address
(
holder
,
CompiledICHolder
::
holder_met
adata
_offset
()));
__
jcc
(
Assembler
::
notEqual
,
missed
);
__
jcc
(
Assembler
::
notEqual
,
missed
);
// Method might have been compiled since the call site was patched to
// Method might have been compiled since the call site was patched to
// interpreted if that is the case treat it as a miss so we can get
// interpreted if that is the case treat it as a miss so we can get
...
...
src/cpu/x86/vm/sharedRuntime_x86_64.cpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
7
, Oracle and/or its affiliates. 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
...
@@ -869,7 +869,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
...
@@ -869,7 +869,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
{
{
__
load_klass
(
temp
,
receiver
);
__
load_klass
(
temp
,
receiver
);
__
cmpptr
(
temp
,
Address
(
holder
,
CompiledICHolder
::
holder_klass_offset
()));
__
cmpptr
(
temp
,
Address
(
holder
,
CompiledICHolder
::
holder_klass_offset
()));
__
movptr
(
rbx
,
Address
(
holder
,
CompiledICHolder
::
holder_met
hod
_offset
()));
__
movptr
(
rbx
,
Address
(
holder
,
CompiledICHolder
::
holder_met
adata
_offset
()));
__
jcc
(
Assembler
::
equal
,
ok
);
__
jcc
(
Assembler
::
equal
,
ok
);
__
jump
(
RuntimeAddress
(
SharedRuntime
::
get_ic_miss_stub
()));
__
jump
(
RuntimeAddress
(
SharedRuntime
::
get_ic_miss_stub
()));
...
...
src/cpu/x86/vm/templateTable_x86_32.cpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. 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
...
@@ -3099,11 +3099,11 @@ void TemplateTable::fast_invokevfinal(int byte_no) {
...
@@ -3099,11 +3099,11 @@ void TemplateTable::fast_invokevfinal(int byte_no) {
void
TemplateTable
::
invokeinterface
(
int
byte_no
)
{
void
TemplateTable
::
invokeinterface
(
int
byte_no
)
{
transition
(
vtos
,
vtos
);
transition
(
vtos
,
vtos
);
assert
(
byte_no
==
f1_byte
,
"use this argument"
);
assert
(
byte_no
==
f1_byte
,
"use this argument"
);
prepare_invoke
(
byte_no
,
rax
,
rbx
,
// get f1 Klass*, f2
itable index
prepare_invoke
(
byte_no
,
rax
,
rbx
,
// get f1 Klass*, f2
Method*
rcx
,
rdx
);
// recv, flags
rcx
,
rdx
);
// recv, flags
// rax:
interfa
ce klass (from f1)
// rax:
referen
ce klass (from f1)
// rbx:
itable index
(from f2)
// rbx:
method
(from f2)
// rcx: receiver
// rcx: receiver
// rdx: flags
// rdx: flags
...
@@ -3124,10 +3124,29 @@ void TemplateTable::invokeinterface(int byte_no) {
...
@@ -3124,10 +3124,29 @@ void TemplateTable::invokeinterface(int byte_no) {
__
null_check
(
rcx
,
oopDesc
::
klass_offset_in_bytes
());
__
null_check
(
rcx
,
oopDesc
::
klass_offset_in_bytes
());
__
load_klass
(
rdx
,
rcx
);
__
load_klass
(
rdx
,
rcx
);
Label
no_such_interface
,
no_such_method
;
// Receiver subtype check against REFC.
// Superklass in rax. Subklass in rdx. Blows rcx, rdi.
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
rdx
,
rax
,
noreg
,
// outputs: scan temp. reg, scan temp. reg
rsi
,
rdi
,
no_such_interface
,
/*return_method=*/
false
);
// profile this call
// profile this call
__
restore_bcp
();
// rbcp was destroyed by receiver type check
__
profile_virtual_call
(
rdx
,
rsi
,
rdi
);
__
profile_virtual_call
(
rdx
,
rsi
,
rdi
);
Label
no_such_interface
,
no_such_method
;
// Get declaring interface class from method, and itable index
__
movptr
(
rax
,
Address
(
rbx
,
Method
::
const_offset
()));
__
movptr
(
rax
,
Address
(
rax
,
ConstMethod
::
constants_offset
()));
__
movptr
(
rax
,
Address
(
rax
,
ConstantPool
::
pool_holder_offset_in_bytes
()));
__
movl
(
rbx
,
Address
(
rbx
,
Method
::
itable_index_offset
()));
__
subl
(
rbx
,
Method
::
itable_index_max
);
__
negl
(
rbx
);
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
rdx
,
rax
,
rbx
,
rdx
,
rax
,
rbx
,
...
...
src/cpu/x86/vm/templateTable_x86_64.cpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 2003, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
7
, Oracle and/or its affiliates. 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
...
@@ -3150,11 +3150,11 @@ void TemplateTable::fast_invokevfinal(int byte_no) {
...
@@ -3150,11 +3150,11 @@ void TemplateTable::fast_invokevfinal(int byte_no) {
void
TemplateTable
::
invokeinterface
(
int
byte_no
)
{
void
TemplateTable
::
invokeinterface
(
int
byte_no
)
{
transition
(
vtos
,
vtos
);
transition
(
vtos
,
vtos
);
assert
(
byte_no
==
f1_byte
,
"use this argument"
);
assert
(
byte_no
==
f1_byte
,
"use this argument"
);
prepare_invoke
(
byte_no
,
rax
,
rbx
,
// get f1 Klass*, f2
itable index
prepare_invoke
(
byte_no
,
rax
,
rbx
,
// get f1 Klass*, f2
Method*
rcx
,
rdx
);
// recv, flags
rcx
,
rdx
);
// recv, flags
// rax:
interfa
ce klass (from f1)
// rax:
referen
ce klass (from f1)
// rbx:
itable index
(from f2)
// rbx:
method
(from f2)
// rcx: receiver
// rcx: receiver
// rdx: flags
// rdx: flags
...
@@ -3175,10 +3175,28 @@ void TemplateTable::invokeinterface(int byte_no) {
...
@@ -3175,10 +3175,28 @@ void TemplateTable::invokeinterface(int byte_no) {
__
null_check
(
rcx
,
oopDesc
::
klass_offset_in_bytes
());
__
null_check
(
rcx
,
oopDesc
::
klass_offset_in_bytes
());
__
load_klass
(
rdx
,
rcx
);
__
load_klass
(
rdx
,
rcx
);
Label
no_such_interface
,
no_such_method
;
// Receiver subtype check against REFC.
// Superklass in rax. Subklass in rdx. Blows rcx, rdi.
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
rdx
,
rax
,
noreg
,
// outputs: scan temp. reg, scan temp. reg
r13
,
r14
,
no_such_interface
,
/*return_method=*/
false
);
// profile this call
// profile this call
__
restore_bcp
();
// rbcp was destroyed by receiver type check
__
profile_virtual_call
(
rdx
,
r13
,
r14
);
__
profile_virtual_call
(
rdx
,
r13
,
r14
);
Label
no_such_interface
,
no_such_method
;
// Get declaring interface class from method, and itable index
__
movptr
(
rax
,
Address
(
rbx
,
Method
::
const_offset
()));
__
movptr
(
rax
,
Address
(
rax
,
ConstMethod
::
constants_offset
()));
__
movptr
(
rax
,
Address
(
rax
,
ConstantPool
::
pool_holder_offset_in_bytes
()));
__
movl
(
rbx
,
Address
(
rbx
,
Method
::
itable_index_offset
()));
__
subl
(
rbx
,
Method
::
itable_index_max
);
__
negl
(
rbx
);
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
rdx
,
rax
,
rbx
,
rdx
,
rax
,
rbx
,
...
...
src/cpu/x86/vm/vtableStubs_x86_32.cpp
浏览文件 @
21b5cc64
/*
/*
* 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.
* 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
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include "code/vtableStubs.hpp"
#include "code/vtableStubs.hpp"
#include "interp_masm_x86.hpp"
#include "interp_masm_x86.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"
...
@@ -147,7 +148,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
...
@@ -147,7 +148,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
MacroAssembler
*
masm
=
new
MacroAssembler
(
&
cb
);
MacroAssembler
*
masm
=
new
MacroAssembler
(
&
cb
);
// Entry arguments:
// Entry arguments:
// rax
,: Interface
// rax
: CompiledICHolder
// rcx: Receiver
// rcx: Receiver
#ifndef PRODUCT
#ifndef PRODUCT
...
@@ -155,25 +156,42 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
...
@@ -155,25 +156,42 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
__
incrementl
(
ExternalAddress
((
address
)
SharedRuntime
::
nof_megamorphic_calls_addr
()));
__
incrementl
(
ExternalAddress
((
address
)
SharedRuntime
::
nof_megamorphic_calls_addr
()));
}
}
#endif
/* PRODUCT */
#endif
/* PRODUCT */
// get receiver (need to skip return address on top of stack)
assert
(
VtableStub
::
receiver_location
()
==
rcx
->
as_VMReg
(),
"receiver expected in rcx"
);
// Most registers are in use; we'll use rax, rbx, rsi, rdi
// (If we need to make rsi, rdi callee-save, do a push/pop here.)
const
Register
recv_klass_reg
=
rsi
;
const
Register
holder_klass_reg
=
rax
;
// declaring interface klass (DECC)
const
Register
resolved_klass_reg
=
rbx
;
// resolved interface klass (REFC)
const
Register
temp_reg
=
rdi
;
const
Register
icholder_reg
=
rax
;
__
movptr
(
resolved_klass_reg
,
Address
(
icholder_reg
,
CompiledICHolder
::
holder_klass_offset
()));
__
movptr
(
holder_klass_reg
,
Address
(
icholder_reg
,
CompiledICHolder
::
holder_metadata_offset
()));
Label
L_no_such_interface
;
// get receiver klass (also an implicit null-check)
// get receiver klass (also an implicit null-check)
address
npe_addr
=
__
pc
();
address
npe_addr
=
__
pc
();
__
movptr
(
rsi
,
Address
(
rcx
,
oopDesc
::
klass_offset_in_bytes
()));
assert
(
VtableStub
::
receiver_location
()
==
rcx
->
as_VMReg
(),
"receiver expected in rcx"
);
__
load_klass
(
recv_klass_reg
,
rcx
);
// Most registers are in use; we'll use rax, rbx, rsi, rdi
// (If we need to make rsi, rdi callee-save, do a push/pop here.)
// Receiver subtype check against REFC.
// Destroys recv_klass_reg value.
__
lookup_interface_method
(
// inputs: rec. class, interface
recv_klass_reg
,
resolved_klass_reg
,
noreg
,
// outputs: scan temp. reg1, scan temp. reg2
recv_klass_reg
,
temp_reg
,
L_no_such_interface
,
/*return_method=*/
false
);
// Get selected method from declaring class and itable index
const
Register
method
=
rbx
;
const
Register
method
=
rbx
;
Label
throw_icce
;
__
load_klass
(
recv_klass_reg
,
rcx
);
// restore recv_klass_reg
// Get Method* and entrypoint for compiler
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
r
si
,
rax
,
itable_index
,
r
ecv_klass_reg
,
holder_klass_reg
,
itable_index
,
// outputs: method, scan temp. reg
// outputs: method, scan temp. reg
method
,
rdi
,
method
,
temp_reg
,
throw_ic
ce
);
L_no_such_interfa
ce
);
// method (rbx): Method*
// method (rbx): Method*
// rcx: receiver
// rcx: receiver
...
@@ -193,9 +211,10 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
...
@@ -193,9 +211,10 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
address
ame_addr
=
__
pc
();
address
ame_addr
=
__
pc
();
__
jmp
(
Address
(
method
,
Method
::
from_compiled_offset
()));
__
jmp
(
Address
(
method
,
Method
::
from_compiled_offset
()));
__
bind
(
throw_ic
ce
);
__
bind
(
L_no_such_interfa
ce
);
__
jump
(
RuntimeAddress
(
StubRoutines
::
throw_IncompatibleClassChangeError_entry
()));
__
jump
(
RuntimeAddress
(
StubRoutines
::
throw_IncompatibleClassChangeError_entry
()));
masm
->
flush
();
__
flush
();
if
(
PrintMiscellaneous
&&
(
WizardMode
||
Verbose
))
{
if
(
PrintMiscellaneous
&&
(
WizardMode
||
Verbose
))
{
tty
->
print_cr
(
"itable #%d at "
PTR_FORMAT
"[%d] left over: %d"
,
tty
->
print_cr
(
"itable #%d at "
PTR_FORMAT
"[%d] left over: %d"
,
...
@@ -220,7 +239,7 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
...
@@ -220,7 +239,7 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
return
(
DebugVtables
?
210
:
16
)
+
(
CountCompiledCalls
?
6
:
0
);
return
(
DebugVtables
?
210
:
16
)
+
(
CountCompiledCalls
?
6
:
0
);
}
else
{
}
else
{
// Itable stub size
// Itable stub size
return
(
DebugVtables
?
256
:
6
6
)
+
(
CountCompiledCalls
?
6
:
0
);
return
(
DebugVtables
?
256
:
11
6
)
+
(
CountCompiledCalls
?
6
:
0
);
}
}
// In order to tune these parameters, run the JVM with VM options
// In order to tune these parameters, run the JVM with VM options
// +PrintMiscellaneous and +WizardMode to see information about
// +PrintMiscellaneous and +WizardMode to see information about
...
...
src/cpu/x86/vm/vtableStubs_x86_64.cpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 2003, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
7
, Oracle and/or its affiliates. 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
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include "code/vtableStubs.hpp"
#include "code/vtableStubs.hpp"
#include "interp_masm_x86.hpp"
#include "interp_masm_x86.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"
...
@@ -149,36 +150,50 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
...
@@ -149,36 +150,50 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
#endif
#endif
// Entry arguments:
// Entry arguments:
// rax:
Interface
// rax:
CompiledICHolder
// j_rarg0: Receiver
// j_rarg0: Receiver
// Free registers (non-args) are rax (interface), rbx
// Most registers are in use; we'll use rax, rbx, r10, r11
// (various calling sequences use r[cd]x, r[sd]i, r[89]; stay away from them)
const
Register
recv_klass_reg
=
r10
;
const
Register
holder_klass_reg
=
rax
;
// declaring interface klass (DECC)
const
Register
resolved_klass_reg
=
rbx
;
// resolved interface klass (REFC)
const
Register
temp_reg
=
r11
;
// get receiver (need to skip return address on top of stack)
Label
L_no_such_interface
;
const
Register
icholder_reg
=
rax
;
__
movptr
(
resolved_klass_reg
,
Address
(
icholder_reg
,
CompiledICHolder
::
holder_klass_offset
()));
__
movptr
(
holder_klass_reg
,
Address
(
icholder_reg
,
CompiledICHolder
::
holder_metadata_offset
()));
assert
(
VtableStub
::
receiver_location
()
==
j_rarg0
->
as_VMReg
(),
"receiver expected in j_rarg0"
);
// get receiver klass (also an implicit null-check)
// get receiver klass (also an implicit null-check)
assert
(
VtableStub
::
receiver_location
()
==
j_rarg0
->
as_VMReg
(),
"receiver expected in j_rarg0"
);
address
npe_addr
=
__
pc
();
address
npe_addr
=
__
pc
();
__
load_klass
(
recv_klass_reg
,
j_rarg0
);
// Most registers are in use; we'll use rax, rbx, r10, r11
// (various calling sequences use r[cd]x, r[sd]i, r[89]; stay away from them)
// Receiver subtype check against REFC.
__
load_klass
(
r10
,
j_rarg0
);
// Destroys recv_klass_reg value.
__
lookup_interface_method
(
// inputs: rec. class, interface
recv_klass_reg
,
resolved_klass_reg
,
noreg
,
// outputs: scan temp. reg1, scan temp. reg2
recv_klass_reg
,
temp_reg
,
L_no_such_interface
,
/*return_method=*/
false
);
// Get selected method from declaring class and itable index
const
Register
method
=
rbx
;
__
load_klass
(
recv_klass_reg
,
j_rarg0
);
// restore recv_klass_reg
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
recv_klass_reg
,
holder_klass_reg
,
itable_index
,
// outputs: method, scan temp. reg
method
,
temp_reg
,
L_no_such_interface
);
// If we take a trap while this arg is on the stack we will not
// If we take a trap while this arg is on the stack we will not
// be able to walk the stack properly. This is not an issue except
// be able to walk the stack properly. This is not an issue except
// when there are mistakes in this assembly code that could generate
// when there are mistakes in this assembly code that could generate
// a spurious fault. Ask me how I know...
// a spurious fault. Ask me how I know...
const
Register
method
=
rbx
;
Label
throw_icce
;
// Get Method* and entrypoint for compiler
__
lookup_interface_method
(
// inputs: rec. class, interface, itable index
r10
,
rax
,
itable_index
,
// outputs: method, scan temp. reg
method
,
r11
,
throw_icce
);
// method (rbx): Method*
// method (rbx): Method*
// j_rarg0: receiver
// j_rarg0: receiver
...
@@ -199,7 +214,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
...
@@ -199,7 +214,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
address
ame_addr
=
__
pc
();
address
ame_addr
=
__
pc
();
__
jmp
(
Address
(
method
,
Method
::
from_compiled_offset
()));
__
jmp
(
Address
(
method
,
Method
::
from_compiled_offset
()));
__
bind
(
throw_ic
ce
);
__
bind
(
L_no_such_interfa
ce
);
__
jump
(
RuntimeAddress
(
StubRoutines
::
throw_IncompatibleClassChangeError_entry
()));
__
jump
(
RuntimeAddress
(
StubRoutines
::
throw_IncompatibleClassChangeError_entry
()));
__
flush
();
__
flush
();
...
@@ -226,8 +241,8 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
...
@@ -226,8 +241,8 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
(
UseCompressedClassPointers
?
MacroAssembler
::
instr_size_for_decode_klass_not_null
()
:
0
);
(
UseCompressedClassPointers
?
MacroAssembler
::
instr_size_for_decode_klass_not_null
()
:
0
);
}
else
{
}
else
{
// Itable stub size
// Itable stub size
return
(
DebugVtables
?
512
:
74
)
+
(
CountCompiledCalls
?
13
:
0
)
+
return
(
DebugVtables
?
512
:
140
)
+
(
CountCompiledCalls
?
13
:
0
)
+
(
UseCompressedClassPointers
?
MacroAssembler
::
instr_size_for_decode_klass_not_null
()
:
0
);
(
UseCompressedClassPointers
?
2
*
MacroAssembler
::
instr_size_for_decode_klass_not_null
()
:
0
);
}
}
// In order to tune these parameters, run the JVM with VM options
// In order to tune these parameters, run the JVM with VM options
// +PrintMiscellaneous and +WizardMode to see information about
// +PrintMiscellaneous and +WizardMode to see information about
...
...
src/share/vm/code/compiledIC.cpp
浏览文件 @
21b5cc64
/*
/*
* 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.
* 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
...
@@ -228,10 +228,13 @@ bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod
...
@@ -228,10 +228,13 @@ bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod
#ifdef ASSERT
#ifdef ASSERT
int
index
=
call_info
->
resolved_method
()
->
itable_index
();
int
index
=
call_info
->
resolved_method
()
->
itable_index
();
assert
(
index
==
itable_index
,
"CallInfo pre-computes this"
);
assert
(
index
==
itable_index
,
"CallInfo pre-computes this"
);
#endif //ASSERT
InstanceKlass
*
k
=
call_info
->
resolved_method
()
->
method_holder
();
InstanceKlass
*
k
=
call_info
->
resolved_method
()
->
method_holder
();
assert
(
k
->
verify_itable_index
(
itable_index
),
"sanity check"
);
assert
(
k
->
verify_itable_index
(
itable_index
),
"sanity check"
);
InlineCacheBuffer
::
create_transition_stub
(
this
,
k
,
entry
);
#endif //ASSERT
CompiledICHolder
*
holder
=
new
CompiledICHolder
(
call_info
->
resolved_method
()
->
method_holder
(),
call_info
->
resolved_klass
()());
holder
->
claim
();
InlineCacheBuffer
::
create_transition_stub
(
this
,
holder
,
entry
);
}
else
{
}
else
{
assert
(
call_info
->
call_kind
()
==
CallInfo
::
vtable_call
,
"either itable or vtable"
);
assert
(
call_info
->
call_kind
()
==
CallInfo
::
vtable_call
,
"either itable or vtable"
);
// Can be different than selected_method->vtable_index(), due to package-private etc.
// Can be different than selected_method->vtable_index(), due to package-private etc.
...
@@ -527,7 +530,14 @@ void CompiledIC::compute_monomorphic_entry(methodHandle method,
...
@@ -527,7 +530,14 @@ void CompiledIC::compute_monomorphic_entry(methodHandle method,
bool
CompiledIC
::
is_icholder_entry
(
address
entry
)
{
bool
CompiledIC
::
is_icholder_entry
(
address
entry
)
{
CodeBlob
*
cb
=
CodeCache
::
find_blob_unsafe
(
entry
);
CodeBlob
*
cb
=
CodeCache
::
find_blob_unsafe
(
entry
);
return
(
cb
!=
NULL
&&
cb
->
is_adapter_blob
());
if
(
cb
!=
NULL
&&
cb
->
is_adapter_blob
())
{
return
true
;
}
// itable stubs also use CompiledICHolder
if
(
VtableStubs
::
is_entry_point
(
entry
)
&&
VtableStubs
::
stub_containing
(
entry
)
->
is_itable_stub
())
{
return
true
;
}
return
false
;
}
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
...
...
src/share/vm/code/compiledIC.hpp
浏览文件 @
21b5cc64
/*
/*
* 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.
* 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
...
@@ -59,11 +59,11 @@
...
@@ -59,11 +59,11 @@
// \ / \ /
// \ / \ /
// [4] \ / [4] \->-/
// [4] \ / [4] \->-/
// \->- Megamorphic -<-/
// \->- Megamorphic -<-/
//
(Method
*)
//
(CompiledICHolder
*)
//
//
// The text in par
anteses () refere
to the value of the inline cache receiver (mov instruction)
// The text in par
entheses () refers
to the value of the inline cache receiver (mov instruction)
//
//
// The numbers in square brackets refer
e
to the kind of transition:
// The numbers in square brackets refer to the kind of transition:
// [1]: Initial fixup. Receiver it found from debug information
// [1]: Initial fixup. Receiver it found from debug information
// [2]: Compilation of a method
// [2]: Compilation of a method
// [3]: Recompilation of a method (note: only entry is changed. The Klass* must stay the same)
// [3]: Recompilation of a method (note: only entry is changed. The Klass* must stay the same)
...
...
src/share/vm/code/nmethod.cpp
浏览文件 @
21b5cc64
...
@@ -1748,12 +1748,11 @@ void static clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_a
...
@@ -1748,12 +1748,11 @@ void static clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_a
CompiledICHolder
*
cichk_oop
=
ic
->
cached_icholder
();
CompiledICHolder
*
cichk_oop
=
ic
->
cached_icholder
();
if
(
mark_on_stack
)
{
if
(
mark_on_stack
)
{
Metadata
::
mark_on_stack
(
cichk_oop
->
holder_met
hod
());
Metadata
::
mark_on_stack
(
cichk_oop
->
holder_met
adata
());
Metadata
::
mark_on_stack
(
cichk_oop
->
holder_klass
());
Metadata
::
mark_on_stack
(
cichk_oop
->
holder_klass
());
}
}
if
(
cichk_oop
->
holder_method
()
->
method_holder
()
->
is_loader_alive
(
is_alive
)
&&
if
(
cichk_oop
->
is_loader_alive
(
is_alive
))
{
cichk_oop
->
holder_klass
()
->
is_loader_alive
(
is_alive
))
{
return
;
return
;
}
}
}
else
{
}
else
{
...
@@ -2180,7 +2179,7 @@ void nmethod::metadata_do(void f(Metadata*)) {
...
@@ -2180,7 +2179,7 @@ void nmethod::metadata_do(void f(Metadata*)) {
CompiledIC
*
ic
=
CompiledIC_at
(
&
iter
);
CompiledIC
*
ic
=
CompiledIC_at
(
&
iter
);
if
(
ic
->
is_icholder_call
())
{
if
(
ic
->
is_icholder_call
())
{
CompiledICHolder
*
cichk
=
ic
->
cached_icholder
();
CompiledICHolder
*
cichk
=
ic
->
cached_icholder
();
f
(
cichk
->
holder_met
hod
());
f
(
cichk
->
holder_met
adata
());
f
(
cichk
->
holder_klass
());
f
(
cichk
->
holder_klass
());
}
else
{
}
else
{
Metadata
*
ic_oop
=
ic
->
cached_metadata
();
Metadata
*
ic_oop
=
ic
->
cached_metadata
();
...
...
src/share/vm/interpreter/interpreterRuntime.cpp
浏览文件 @
21b5cc64
...
@@ -786,6 +786,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
...
@@ -786,6 +786,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
case
CallInfo
::
itable_call
:
case
CallInfo
::
itable_call
:
cache_entry
(
thread
)
->
set_itable_call
(
cache_entry
(
thread
)
->
set_itable_call
(
bytecode
,
bytecode
,
info
.
resolved_klass
(),
info
.
resolved_method
(),
info
.
resolved_method
(),
info
.
itable_index
());
info
.
itable_index
());
break
;
break
;
...
...
src/share/vm/oops/compiledICHolder.cpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 1998, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 201
7
, Oracle and/or its affiliates. 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
...
@@ -32,12 +32,28 @@ volatile int CompiledICHolder::_live_count;
...
@@ -32,12 +32,28 @@ volatile int CompiledICHolder::_live_count;
volatile
int
CompiledICHolder
::
_live_not_claimed_count
;
volatile
int
CompiledICHolder
::
_live_not_claimed_count
;
bool
CompiledICHolder
::
is_loader_alive
(
BoolObjectClosure
*
is_alive
)
{
if
(
_holder_metadata
->
is_method
())
{
if
(
!
((
Method
*
)
_holder_metadata
)
->
method_holder
()
->
is_loader_alive
(
is_alive
))
{
return
false
;
}
}
else
if
(
_holder_metadata
->
is_klass
())
{
if
(
!
((
Klass
*
)
_holder_metadata
)
->
is_loader_alive
(
is_alive
))
{
return
false
;
}
}
if
(
!
_holder_klass
->
is_loader_alive
(
is_alive
))
{
return
false
;
}
return
true
;
}
// Printing
// Printing
void
CompiledICHolder
::
print_on
(
outputStream
*
st
)
const
{
void
CompiledICHolder
::
print_on
(
outputStream
*
st
)
const
{
st
->
print
(
"%s"
,
internal_name
());
st
->
print
(
"%s"
,
internal_name
());
st
->
print
(
" - met
hod: "
);
holder_method
()
->
print_value_on
(
st
);
st
->
cr
();
st
->
print
(
" - met
adata: "
);
holder_metadata
()
->
print_value_on
(
st
);
st
->
cr
();
st
->
print
(
" - klass: "
);
holder_klass
()
->
print_value_on
(
st
);
st
->
cr
();
st
->
print
(
" - klass:
"
);
holder_klass
()
->
print_value_on
(
st
);
st
->
cr
();
}
}
void
CompiledICHolder
::
print_value_on
(
outputStream
*
st
)
const
{
void
CompiledICHolder
::
print_value_on
(
outputStream
*
st
)
const
{
...
@@ -48,6 +64,6 @@ void CompiledICHolder::print_value_on(outputStream* st) const {
...
@@ -48,6 +64,6 @@ void CompiledICHolder::print_value_on(outputStream* st) const {
// Verification
// Verification
void
CompiledICHolder
::
verify_on
(
outputStream
*
st
)
{
void
CompiledICHolder
::
verify_on
(
outputStream
*
st
)
{
guarantee
(
holder_met
hod
()
->
is_method
(),
"should be method
"
);
guarantee
(
holder_met
adata
()
->
is_method
()
||
holder_metadata
()
->
is_klass
(),
"should be method or klass
"
);
guarantee
(
holder_klass
()
->
is_klass
(),
"should be klass"
);
guarantee
(
holder_klass
()
->
is_klass
(),
"should be klass"
);
}
}
src/share/vm/oops/compiledICHolder.hpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 1998, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 201
7
, Oracle and/or its affiliates. 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
...
@@ -28,8 +28,9 @@
...
@@ -28,8 +28,9 @@
#include "oops/oop.hpp"
#include "oops/oop.hpp"
// A CompiledICHolder* is a helper object for the inline cache implementation.
// A CompiledICHolder* is a helper object for the inline cache implementation.
// It holds an intermediate value (method+klass pair) used when converting from
// It holds:
// compiled to an interpreted call.
// (1) (method+klass pair) when converting from compiled to an interpreted call
// (2) (klass+klass pair) when calling itable stub from megamorphic compiled call
//
//
// These are always allocated in the C heap and are freed during a
// These are always allocated in the C heap and are freed during a
// safepoint by the ICBuffer logic. It's unsafe to free them earlier
// safepoint by the ICBuffer logic. It's unsafe to free them earlier
...
@@ -44,14 +45,14 @@ class CompiledICHolder : public CHeapObj<mtCompiler> {
...
@@ -44,14 +45,14 @@ class CompiledICHolder : public CHeapObj<mtCompiler> {
static
volatile
int
_live_not_claimed_count
;
// allocated but not yet in use so not
static
volatile
int
_live_not_claimed_count
;
// allocated but not yet in use so not
// reachable by iterating over nmethods
// reachable by iterating over nmethods
Met
hod
*
_holder_method
;
Met
adata
*
_holder_metadata
;
Klass
*
_holder_klass
;
// to avoid name conflict with oopDesc::_klass
Klass
*
_holder_klass
;
// to avoid name conflict with oopDesc::_klass
CompiledICHolder
*
_next
;
CompiledICHolder
*
_next
;
public:
public:
// Constructor
// Constructor
CompiledICHolder
(
Met
hod
*
method
,
Klass
*
klass
)
CompiledICHolder
(
Met
adata
*
metadata
,
Klass
*
klass
)
:
_holder_met
hod
(
method
),
_holder_klass
(
klass
)
{
:
_holder_met
adata
(
metadata
),
_holder_klass
(
klass
)
{
#ifdef ASSERT
#ifdef ASSERT
Atomic
::
inc
(
&
_live_count
);
Atomic
::
inc
(
&
_live_count
);
Atomic
::
inc
(
&
_live_not_claimed_count
);
Atomic
::
inc
(
&
_live_not_claimed_count
);
...
@@ -69,19 +70,20 @@ class CompiledICHolder : public CHeapObj<mtCompiler> {
...
@@ -69,19 +70,20 @@ class CompiledICHolder : public CHeapObj<mtCompiler> {
static
int
live_not_claimed_count
()
{
return
_live_not_claimed_count
;
}
static
int
live_not_claimed_count
()
{
return
_live_not_claimed_count
;
}
// accessors
// accessors
Method
*
holder_method
()
const
{
return
_holder_method
;
}
Klass
*
holder_klass
()
const
{
return
_holder_klass
;
}
Klass
*
holder_klass
()
const
{
return
_holder_klass
;
}
Metadata
*
holder_metadata
()
const
{
return
_holder_metadata
;
}
void
set_holder_met
hod
(
Method
*
m
)
{
_holder_method
=
m
;
}
void
set_holder_met
adata
(
Metadata
*
m
)
{
_holder_metadata
=
m
;
}
void
set_holder_klass
(
Klass
*
k
)
{
_holder_klass
=
k
;
}
void
set_holder_klass
(
Klass
*
k
)
{
_holder_klass
=
k
;
}
// interpreter support (offsets in bytes)
static
int
holder_metadata_offset
()
{
return
offset_of
(
CompiledICHolder
,
_holder_metadata
);
}
static
int
holder_method_offset
()
{
return
offset_of
(
CompiledICHolder
,
_holder_method
);
}
static
int
holder_klass_offset
()
{
return
offset_of
(
CompiledICHolder
,
_holder_klass
);
}
static
int
holder_klass_offset
()
{
return
offset_of
(
CompiledICHolder
,
_holder_klass
);
}
CompiledICHolder
*
next
()
{
return
_next
;
}
CompiledICHolder
*
next
()
{
return
_next
;
}
void
set_next
(
CompiledICHolder
*
n
)
{
_next
=
n
;
}
void
set_next
(
CompiledICHolder
*
n
)
{
_next
=
n
;
}
bool
is_loader_alive
(
BoolObjectClosure
*
is_alive
);
// Verify
// Verify
void
verify_on
(
outputStream
*
st
);
void
verify_on
(
outputStream
*
st
);
...
...
src/share/vm/oops/cpCache.cpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 1998, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 201
7
, Oracle and/or its affiliates. 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
...
@@ -259,14 +259,16 @@ void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, method
...
@@ -259,14 +259,16 @@ void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, method
set_direct_or_vtable_call
(
invoke_code
,
method
,
index
,
false
);
set_direct_or_vtable_call
(
invoke_code
,
method
,
index
,
false
);
}
}
void
ConstantPoolCacheEntry
::
set_itable_call
(
Bytecodes
::
Code
invoke_code
,
methodHandle
method
,
int
index
)
{
void
ConstantPoolCacheEntry
::
set_itable_call
(
Bytecodes
::
Code
invoke_code
,
KlassHandle
referenced_klass
,
methodHandle
method
,
int
index
)
{
assert
(
method
->
method_holder
()
->
verify_itable_index
(
index
),
""
);
assert
(
method
->
method_holder
()
->
verify_itable_index
(
index
),
""
);
assert
(
invoke_code
==
Bytecodes
::
_invokeinterface
,
""
);
assert
(
invoke_code
==
Bytecodes
::
_invokeinterface
,
""
);
InstanceKlass
*
interf
=
method
->
method_holder
();
InstanceKlass
*
interf
=
method
->
method_holder
();
assert
(
interf
->
is_interface
(),
"must be an interface"
);
assert
(
interf
->
is_interface
(),
"must be an interface"
);
assert
(
!
method
->
is_final_method
(),
"interfaces do not have final methods; cannot link to one here"
);
assert
(
!
method
->
is_final_method
(),
"interfaces do not have final methods; cannot link to one here"
);
set_f1
(
interf
);
set_f1
(
referenced_klass
()
);
set_f2
(
index
);
set_f2
(
(
intx
)
method
()
);
set_method_flags
(
as_TosState
(
method
->
result_type
()),
set_method_flags
(
as_TosState
(
method
->
result_type
()),
0
,
// no option bits
0
,
// no option bits
method
()
->
size_of_parameters
());
method
()
->
size_of_parameters
());
...
@@ -433,10 +435,27 @@ oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) {
...
@@ -433,10 +435,27 @@ oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) {
#if INCLUDE_JVMTI
#if INCLUDE_JVMTI
void
log_adjust
(
const
char
*
entry_type
,
Method
*
old_method
,
Method
*
new_method
,
bool
*
trace_name_printed
)
{
if
(
RC_TRACE_IN_RANGE
(
0x00100000
,
0x00400000
))
{
if
(
!
(
*
trace_name_printed
))
{
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG
((
"adjust: name=%s"
,
old_method
->
method_holder
()
->
external_name
()));
*
trace_name_printed
=
true
;
}
// RC_TRACE macro has an embedded ResourceMark
RC_TRACE
(
0x00400000
,
(
"cpc %s entry update: %s(%s)"
,
entry_type
,
new_method
->
name
()
->
as_C_string
(),
new_method
->
signature
()
->
as_C_string
()));
}
}
// RedefineClasses() API support:
// RedefineClasses() API support:
// If this ConstantPoolCacheEntry refers to old_method then update it
// If this ConstantPoolCacheEntry refers to old_method then update it
// to refer to new_method.
// to refer to new_method.
bool
ConstantPoolCacheEntry
::
adjust_method_entry
(
Method
*
old_method
,
void
ConstantPoolCacheEntry
::
adjust_method_entry
(
Method
*
old_method
,
Method
*
new_method
,
bool
*
trace_name_printed
)
{
Method
*
new_method
,
bool
*
trace_name_printed
)
{
if
(
is_vfinal
())
{
if
(
is_vfinal
())
{
...
@@ -445,69 +464,34 @@ bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
...
@@ -445,69 +464,34 @@ bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
// match old_method so need an update
// match old_method so need an update
// NOTE: can't use set_f2_as_vfinal_method as it asserts on different values
// NOTE: can't use set_f2_as_vfinal_method as it asserts on different values
_f2
=
(
intptr_t
)
new_method
;
_f2
=
(
intptr_t
)
new_method
;
if
(
RC_TRACE_IN_RANGE
(
0x00100000
,
0x00400000
))
{
if
(
!
(
*
trace_name_printed
))
{
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG
((
"adjust: name=%s"
,
old_method
->
method_holder
()
->
external_name
()));
*
trace_name_printed
=
true
;
}
// RC_TRACE macro has an embedded ResourceMark
RC_TRACE
(
0x00400000
,
(
"cpc vf-entry update: %s(%s)"
,
new_method
->
name
()
->
as_C_string
(),
new_method
->
signature
()
->
as_C_string
()));
}
return
true
;
}
}
return
;
// f1() is not used with virtual entries so bail out
return
false
;
}
}
if
(
_f1
==
NULL
)
{
assert
(
_f1
!=
NULL
,
"should not call with uninteresting entry"
);
// NULL f1() means this is a virtual entry so bail out
// We are assuming that the vtable index does not need change.
return
false
;
}
if
(
_f1
==
old_method
)
{
if
(
!
(
_f1
->
is_method
()))
{
_f1
=
new_method
;
// _f1 is a Klass* for an interface, _f2 is the method
if
(
RC_TRACE_IN_RANGE
(
0x00100000
,
0x00400000
))
{
if
(
f2_as_interface_method
()
==
old_method
)
{
if
(
!
(
*
trace_name_printed
))
{
_f2
=
(
intptr_t
)
new_method
;
// RC_TRACE_MESG macro has an embedded ResourceMark
log_adjust
(
"interface"
,
old_method
,
new_method
,
trace_name_printed
);
RC_TRACE_MESG
((
"adjust: name=%s"
,
old_method
->
method_holder
()
->
external_name
()));
*
trace_name_printed
=
true
;
}
// RC_TRACE macro has an embedded ResourceMark
RC_TRACE
(
0x00400000
,
(
"cpc entry update: %s(%s)"
,
new_method
->
name
()
->
as_C_string
(),
new_method
->
signature
()
->
as_C_string
()));
}
}
return
true
;
}
else
if
(
_f1
==
old_method
)
{
_f1
=
new_method
;
log_adjust
(
"special, static or dynamic"
,
old_method
,
new_method
,
trace_name_printed
);
}
}
return
false
;
}
}
// a constant pool cache entry should never contain old or obsolete methods
// a constant pool cache entry should never contain old or obsolete methods
bool
ConstantPoolCacheEntry
::
check_no_old_or_obsolete_entries
()
{
bool
ConstantPoolCacheEntry
::
check_no_old_or_obsolete_entries
()
{
if
(
is_vfinal
())
{
Method
*
m
=
get_interesting_method_entry
(
NULL
);
// virtual and final so _f2 contains method ptr instead of vtable index
// return false if m refers to a non-deleted old or obsolete method
Metadata
*
f2
=
(
Metadata
*
)
_f2
;
if
(
m
!=
NULL
)
{
// Return false if _f2 refers to an old or an obsolete method.
assert
(
m
->
is_valid
()
&&
m
->
is_method
(),
"m is a valid method"
);
// _f2 == NULL || !_f2->is_method() are just as unexpected here.
return
!
m
->
is_old
()
&&
!
m
->
is_obsolete
();
// old is always set for old and obsolete
return
(
f2
!=
NULL
NOT_PRODUCT
(
&&
f2
->
is_valid
())
&&
f2
->
is_method
()
&&
}
else
{
!
((
Method
*
)
f2
)
->
is_old
()
&&
!
((
Method
*
)
f2
)
->
is_obsolete
());
}
else
if
(
_f1
==
NULL
||
(
NOT_PRODUCT
(
_f1
->
is_valid
()
&&
)
!
_f1
->
is_method
()))
{
// _f1 == NULL || !_f1->is_method() are OK here
return
true
;
return
true
;
}
}
// return false if _f1 refers to a non-deleted old or obsolete method
return
(
NOT_PRODUCT
(
_f1
->
is_valid
()
&&
)
_f1
->
is_method
()
&&
(
f1_as_method
()
->
is_deleted
()
||
(
!
f1_as_method
()
->
is_old
()
&&
!
f1_as_method
()
->
is_obsolete
())));
}
}
Method
*
ConstantPoolCacheEntry
::
get_interesting_method_entry
(
Klass
*
k
)
{
Method
*
ConstantPoolCacheEntry
::
get_interesting_method_entry
(
Klass
*
k
)
{
...
@@ -524,10 +508,11 @@ Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) {
...
@@ -524,10 +508,11 @@ Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) {
return
NULL
;
return
NULL
;
}
else
{
}
else
{
if
(
!
(
_f1
->
is_method
()))
{
if
(
!
(
_f1
->
is_method
()))
{
// _f1 can also contain a Klass* for an interface
// _f1 is a Klass* for an interface
return
NULL
;
m
=
f2_as_interface_method
();
}
else
{
m
=
f1_as_method
();
}
}
m
=
f1_as_method
();
}
}
assert
(
m
!=
NULL
&&
m
->
is_method
(),
"sanity check"
);
assert
(
m
!=
NULL
&&
m
->
is_method
(),
"sanity check"
);
if
(
m
==
NULL
||
!
m
->
is_method
()
||
(
k
!=
NULL
&&
m
->
method_holder
()
!=
k
))
{
if
(
m
==
NULL
||
!
m
->
is_method
()
||
(
k
!=
NULL
&&
m
->
method_holder
()
!=
k
))
{
...
...
src/share/vm/oops/cpCache.hpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 1998, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 201
7
, Oracle and/or its affiliates. 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
...
@@ -248,6 +248,7 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
...
@@ -248,6 +248,7 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
void
set_itable_call
(
void
set_itable_call
(
Bytecodes
::
Code
invoke_code
,
// the bytecode used; must be invokeinterface
Bytecodes
::
Code
invoke_code
,
// the bytecode used; must be invokeinterface
KlassHandle
referenced_klass
,
// the referenced klass in the InterfaceMethodref
methodHandle
method
,
// the resolved interface method
methodHandle
method
,
// the resolved interface method
int
itable_index
// index into itable for the method
int
itable_index
// index into itable for the method
);
);
...
@@ -344,6 +345,7 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
...
@@ -344,6 +345,7 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
bool
is_f1_null
()
const
{
Metadata
*
f1
=
f1_ord
();
return
f1
==
NULL
;
}
// classifies a CPC entry as unbound
bool
is_f1_null
()
const
{
Metadata
*
f1
=
f1_ord
();
return
f1
==
NULL
;
}
// classifies a CPC entry as unbound
int
f2_as_index
()
const
{
assert
(
!
is_vfinal
(),
""
);
return
(
int
)
_f2
;
}
int
f2_as_index
()
const
{
assert
(
!
is_vfinal
(),
""
);
return
(
int
)
_f2
;
}
Method
*
f2_as_vfinal_method
()
const
{
assert
(
is_vfinal
(),
""
);
return
(
Method
*
)
_f2
;
}
Method
*
f2_as_vfinal_method
()
const
{
assert
(
is_vfinal
(),
""
);
return
(
Method
*
)
_f2
;
}
Method
*
f2_as_interface_method
()
const
{
assert
(
bytecode_1
()
==
Bytecodes
::
_invokeinterface
,
""
);
return
(
Method
*
)
_f2
;
}
int
field_index
()
const
{
assert
(
is_field_entry
(),
""
);
return
(
_flags
&
field_index_mask
);
}
int
field_index
()
const
{
assert
(
is_field_entry
(),
""
);
return
(
_flags
&
field_index_mask
);
}
int
parameter_size
()
const
{
assert
(
is_method_entry
(),
""
);
return
(
_flags
&
parameter_size_mask
);
}
int
parameter_size
()
const
{
assert
(
is_method_entry
(),
""
);
return
(
_flags
&
parameter_size_mask
);
}
bool
is_volatile
()
const
{
return
(
_flags
&
(
1
<<
is_volatile_shift
))
!=
0
;
}
bool
is_volatile
()
const
{
return
(
_flags
&
(
1
<<
is_volatile_shift
))
!=
0
;
}
...
@@ -374,7 +376,7 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
...
@@ -374,7 +376,7 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
// trace_name_printed is set to true if the current call has
// trace_name_printed is set to true if the current call has
// printed the klass name so that other routines in the adjust_*
// printed the klass name so that other routines in the adjust_*
// group don't print the klass name.
// group don't print the klass name.
bool
adjust_method_entry
(
Method
*
old_method
,
Method
*
new_method
,
void
adjust_method_entry
(
Method
*
old_method
,
Method
*
new_method
,
bool
*
trace_name_printed
);
bool
*
trace_name_printed
);
bool
check_no_old_or_obsolete_entries
();
bool
check_no_old_or_obsolete_entries
();
Method
*
get_interesting_method_entry
(
Klass
*
k
);
Method
*
get_interesting_method_entry
(
Klass
*
k
);
...
...
src/share/vm/oops/klassVtable.cpp
浏览文件 @
21b5cc64
...
@@ -1204,7 +1204,6 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
...
@@ -1204,7 +1204,6 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
Array
<
Method
*>*
methods
=
InstanceKlass
::
cast
(
interf_h
())
->
methods
();
Array
<
Method
*>*
methods
=
InstanceKlass
::
cast
(
interf_h
())
->
methods
();
int
nof_methods
=
methods
->
length
();
int
nof_methods
=
methods
->
length
();
HandleMark
hm
;
HandleMark
hm
;
assert
(
nof_methods
>
0
,
"at least one method must exist for interface to be in vtable"
);
Handle
interface_loader
(
THREAD
,
InstanceKlass
::
cast
(
interf_h
())
->
class_loader
());
Handle
interface_loader
(
THREAD
,
InstanceKlass
::
cast
(
interf_h
())
->
class_loader
());
int
ime_count
=
method_count_for_interface
(
interf_h
());
int
ime_count
=
method_count_for_interface
(
interf_h
());
...
@@ -1386,8 +1385,10 @@ void visit_all_interfaces(Array<Klass*>* transitive_intf, InterfaceVisiterClosur
...
@@ -1386,8 +1385,10 @@ void visit_all_interfaces(Array<Klass*>* transitive_intf, InterfaceVisiterClosur
}
}
}
}
// Only count interfaces with at least one method
// Visit all interfaces which either have any methods or can participate in receiver type check.
if
(
method_count
>
0
)
{
// We do not bother to count methods in transitive interfaces, although that would allow us to skip
// this step in the rare case of a zero-method interface extending another zero-method interface.
if
(
method_count
>
0
||
InstanceKlass
::
cast
(
intf
)
->
transitive_interfaces
()
->
length
()
>
0
)
{
blk
->
doit
(
intf
,
method_count
);
blk
->
doit
(
intf
,
method_count
);
}
}
}
}
...
...
src/share/vm/oops/method.hpp
浏览文件 @
21b5cc64
/*
/*
* Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. 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
...
@@ -661,6 +661,7 @@ class Method : public Metadata {
...
@@ -661,6 +661,7 @@ class Method : public Metadata {
static
ByteSize
from_interpreted_offset
()
{
return
byte_offset_of
(
Method
,
_from_interpreted_entry
);
}
static
ByteSize
from_interpreted_offset
()
{
return
byte_offset_of
(
Method
,
_from_interpreted_entry
);
}
static
ByteSize
interpreter_entry_offset
()
{
return
byte_offset_of
(
Method
,
_i2i_entry
);
}
static
ByteSize
interpreter_entry_offset
()
{
return
byte_offset_of
(
Method
,
_i2i_entry
);
}
static
ByteSize
signature_handler_offset
()
{
return
in_ByteSize
(
sizeof
(
Method
)
+
wordSize
);
}
static
ByteSize
signature_handler_offset
()
{
return
in_ByteSize
(
sizeof
(
Method
)
+
wordSize
);
}
static
ByteSize
itable_index_offset
()
{
return
byte_offset_of
(
Method
,
_vtable_index
);
}
// for code generation
// for code generation
static
int
method_data_offset_in_bytes
()
{
return
offset_of
(
Method
,
_method_data
);
}
static
int
method_data_offset_in_bytes
()
{
return
offset_of
(
Method
,
_method_data
);
}
...
...
src/share/vm/runtime/vmStructs.cpp
浏览文件 @
21b5cc64
...
@@ -278,7 +278,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
...
@@ -278,7 +278,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
volatile_nonstatic_field(ArrayKlass, _lower_dimension, Klass*) \
volatile_nonstatic_field(ArrayKlass, _lower_dimension, Klass*) \
nonstatic_field(ArrayKlass, _vtable_len, int) \
nonstatic_field(ArrayKlass, _vtable_len, int) \
nonstatic_field(ArrayKlass, _component_mirror, oop) \
nonstatic_field(ArrayKlass, _component_mirror, oop) \
nonstatic_field(CompiledICHolder, _holder_met
hod, Method*)
\
nonstatic_field(CompiledICHolder, _holder_met
adata, Metadata*)
\
nonstatic_field(CompiledICHolder, _holder_klass, Klass*) \
nonstatic_field(CompiledICHolder, _holder_klass, Klass*) \
nonstatic_field(ConstantPool, _tags, Array<u1>*) \
nonstatic_field(ConstantPool, _tags, Array<u1>*) \
nonstatic_field(ConstantPool, _cache, ConstantPoolCache*) \
nonstatic_field(ConstantPool, _cache, ConstantPoolCache*) \
...
...
test/runtime/RedefineTests/RedefineInterfaceCall.java
0 → 100644
浏览文件 @
21b5cc64
/*
* Copyright (c) 2017, 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.
*/
/*
* @test
* @bug 8174962
* @summary Redefine class with interface method call
* @library /testlibrary /test/lib
* @modules java.base/jdk.internal.misc
* @modules java.compiler
* java.instrument
* jdk.jartool/sun.tools.jar
* @run main RedefineClassHelper
* @run main/othervm -javaagent:redefineagent.jar RedefineInterfaceCall
*/
import
static
jdk
.
testlibrary
.
Asserts
.
assertEquals
;
interface
I1
{
default
int
m
()
{
return
0
;
}
}
interface
I2
extends
I1
{}
public
class
RedefineInterfaceCall
{
public
static
class
C
implements
I2
{
public
int
test
(
I2
i
)
{
return
i
.
m
();
// invokeinterface cpCacheEntry
}
}
static
String
newI1
=
"interface I1 { default int m() { return 1; } }"
;
static
String
newC
=
"public class RedefineInterfaceCall$C implements I2 { "
+
" public int test(I2 i) { "
+
" return i.m(); "
+
" } "
+
"} "
;
static
int
test
(
I2
i
)
{
return
i
.
m
();
// invokeinterface cpCacheEntry
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
C
c
=
new
C
();
assertEquals
(
test
(
c
),
0
);
assertEquals
(
c
.
test
(
c
),
0
);
RedefineClassHelper
.
redefineClass
(
C
.
class
,
newC
);
assertEquals
(
c
.
test
(
c
),
0
);
RedefineClassHelper
.
redefineClass
(
I1
.
class
,
newI1
);
assertEquals
(
test
(
c
),
1
);
assertEquals
(
c
.
test
(
c
),
1
);
RedefineClassHelper
.
redefineClass
(
C
.
class
,
newC
);
assertEquals
(
c
.
test
(
c
),
1
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录