Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
9ae3a3cd
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看板
提交
9ae3a3cd
编写于
1月 20, 2010
作者:
N
never
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6911204: generated adapters with large signatures can fill up the code cache
Reviewed-by: kvn, jrose
上级
0b9139fb
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
373 addition
and
131 deletion
+373
-131
src/cpu/sparc/vm/sharedRuntime_sparc.cpp
src/cpu/sparc/vm/sharedRuntime_sparc.cpp
+4
-3
src/cpu/x86/vm/sharedRuntime_x86_32.cpp
src/cpu/x86/vm/sharedRuntime_x86_32.cpp
+4
-3
src/cpu/x86/vm/sharedRuntime_x86_64.cpp
src/cpu/x86/vm/sharedRuntime_x86_64.cpp
+4
-3
src/share/vm/includeDB_core
src/share/vm/includeDB_core
+4
-0
src/share/vm/oops/methodOop.cpp
src/share/vm/oops/methodOop.cpp
+1
-1
src/share/vm/runtime/sharedRuntime.cpp
src/share/vm/runtime/sharedRuntime.cpp
+322
-92
src/share/vm/runtime/sharedRuntime.hpp
src/share/vm/runtime/sharedRuntime.hpp
+34
-29
未找到文件。
src/cpu/sparc/vm/sharedRuntime_sparc.cpp
浏览文件 @
9ae3a3cd
/*
* Copyright 2003-20
09
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2003-20
10
Sun Microsystems, Inc. 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
...
...
@@ -1189,7 +1189,8 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
// VMReg max_arg,
int
comp_args_on_stack
,
// VMRegStackSlots
const
BasicType
*
sig_bt
,
const
VMRegPair
*
regs
)
{
const
VMRegPair
*
regs
,
AdapterFingerPrint
*
fingerprint
)
{
address
i2c_entry
=
__
pc
();
AdapterGenerator
agen
(
masm
);
...
...
@@ -1258,7 +1259,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
agen
.
gen_c2i_adapter
(
total_args_passed
,
comp_args_on_stack
,
sig_bt
,
regs
,
skip_fixup
);
__
flush
();
return
new
AdapterHandlerEntry
(
i2c_entry
,
c2i_entry
,
c2i_unverified_entry
);
return
AdapterHandlerLibrary
::
new_entry
(
fingerprint
,
i2c_entry
,
c2i_entry
,
c2i_unverified_entry
);
}
...
...
src/cpu/x86/vm/sharedRuntime_x86_32.cpp
浏览文件 @
9ae3a3cd
/*
* Copyright 2003-20
09
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2003-20
10
Sun Microsystems, Inc. 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
...
...
@@ -907,7 +907,8 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
int
total_args_passed
,
int
comp_args_on_stack
,
const
BasicType
*
sig_bt
,
const
VMRegPair
*
regs
)
{
const
VMRegPair
*
regs
,
AdapterFingerPrint
*
fingerprint
)
{
address
i2c_entry
=
__
pc
();
gen_i2c_adapter
(
masm
,
total_args_passed
,
comp_args_on_stack
,
sig_bt
,
regs
);
...
...
@@ -954,7 +955,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
gen_c2i_adapter
(
masm
,
total_args_passed
,
comp_args_on_stack
,
sig_bt
,
regs
,
skip_fixup
);
__
flush
();
return
new
AdapterHandlerEntry
(
i2c_entry
,
c2i_entry
,
c2i_unverified_entry
);
return
AdapterHandlerLibrary
::
new_entry
(
fingerprint
,
i2c_entry
,
c2i_entry
,
c2i_unverified_entry
);
}
int
SharedRuntime
::
c_calling_convention
(
const
BasicType
*
sig_bt
,
...
...
src/cpu/x86/vm/sharedRuntime_x86_64.cpp
浏览文件 @
9ae3a3cd
/*
* Copyright 2003-20
09
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2003-20
10
Sun Microsystems, Inc. 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
...
...
@@ -778,7 +778,8 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
int
total_args_passed
,
int
comp_args_on_stack
,
const
BasicType
*
sig_bt
,
const
VMRegPair
*
regs
)
{
const
VMRegPair
*
regs
,
AdapterFingerPrint
*
fingerprint
)
{
address
i2c_entry
=
__
pc
();
gen_i2c_adapter
(
masm
,
total_args_passed
,
comp_args_on_stack
,
sig_bt
,
regs
);
...
...
@@ -824,7 +825,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
gen_c2i_adapter
(
masm
,
total_args_passed
,
comp_args_on_stack
,
sig_bt
,
regs
,
skip_fixup
);
__
flush
();
return
new
AdapterHandlerEntry
(
i2c_entry
,
c2i_entry
,
c2i_unverified_entry
);
return
AdapterHandlerLibrary
::
new_entry
(
fingerprint
,
i2c_entry
,
c2i_entry
,
c2i_unverified_entry
);
}
int
SharedRuntime
::
c_calling_convention
(
const
BasicType
*
sig_bt
,
...
...
src/share/vm/includeDB_core
浏览文件 @
9ae3a3cd
...
...
@@ -921,6 +921,7 @@ classFileStream.hpp top.hpp
classLoader.cpp allocation.inline.hpp
classLoader.cpp arguments.hpp
classLoader.cpp bytecodeStream.hpp
classLoader.cpp classFileParser.hpp
classLoader.cpp classFileStream.hpp
classLoader.cpp classLoader.hpp
...
...
@@ -948,6 +949,7 @@ classLoader.cpp jvm_misc.hpp
classLoader.cpp management.hpp
classLoader.cpp oop.inline.hpp
classLoader.cpp oopFactory.hpp
classLoader.cpp oopMapCache.hpp
classLoader.cpp os_<os_family>.inline.hpp
classLoader.cpp symbolOop.hpp
classLoader.cpp systemDictionary.hpp
...
...
@@ -3724,6 +3726,7 @@ sharedRuntime.cpp events.hpp
sharedRuntime.cpp forte.hpp
sharedRuntime.cpp gcLocker.inline.hpp
sharedRuntime.cpp handles.inline.hpp
sharedRuntime.cpp hashtable.inline.hpp
sharedRuntime.cpp init.hpp
sharedRuntime.cpp interfaceSupport.hpp
sharedRuntime.cpp interpreterRuntime.hpp
...
...
@@ -3751,6 +3754,7 @@ sharedRuntime.cpp xmlstream.hpp
sharedRuntime.hpp allocation.hpp
sharedRuntime.hpp bytecodeHistogram.hpp
sharedRuntime.hpp bytecodeTracer.hpp
sharedRuntime.hpp hashtable.hpp
sharedRuntime.hpp linkResolver.hpp
sharedRuntime.hpp resourceArea.hpp
sharedRuntime.hpp threadLocalStorage.hpp
...
...
src/share/vm/oops/methodOop.cpp
浏览文件 @
9ae3a3cd
...
...
@@ -688,7 +688,7 @@ address methodOopDesc::make_adapters(methodHandle mh, TRAPS) {
// so making them eagerly shouldn't be too expensive.
AdapterHandlerEntry
*
adapter
=
AdapterHandlerLibrary
::
get_adapter
(
mh
);
if
(
adapter
==
NULL
)
{
THROW_
0
(
vmSymbols
::
java_lang_OutOfMemoryError
()
);
THROW_
MSG_NULL
(
vmSymbols
::
java_lang_VirtualMachineError
(),
"out of space in CodeCache for adapters"
);
}
mh
->
set_adapter_entry
(
adapter
);
...
...
src/share/vm/runtime/sharedRuntime.cpp
浏览文件 @
9ae3a3cd
/*
* Copyright 1997-20
09
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-20
10
Sun Microsystems, Inc. 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
...
...
@@ -1680,6 +1680,8 @@ void SharedRuntime::print_statistics() {
if
(
_find_handler_ctr
)
tty
->
print_cr
(
"%5d find exception handler"
,
_find_handler_ctr
);
if
(
_rethrow_ctr
)
tty
->
print_cr
(
"%5d rethrow handler"
,
_rethrow_ctr
);
AdapterHandlerLibrary
::
print_statistics
();
if
(
xtty
!=
NULL
)
xtty
->
tail
(
"statistics"
);
}
...
...
@@ -1780,11 +1782,258 @@ void SharedRuntime::print_call_statistics(int comp_total) {
#endif
// A simple wrapper class around the calling convention information
// that allows sharing of adapters for the same calling convention.
class
AdapterFingerPrint
:
public
CHeapObj
{
private:
union
{
signed
char
_compact
[
12
];
int
_compact_int
[
3
];
intptr_t
*
_fingerprint
;
}
_value
;
int
_length
;
// A negative length indicates that _value._fingerprint is the array.
// Otherwise it's in the compact form.
public:
AdapterFingerPrint
(
int
total_args_passed
,
VMRegPair
*
regs
)
{
assert
(
sizeof
(
_value
.
_compact
)
==
sizeof
(
_value
.
_compact_int
),
"must match"
);
_length
=
total_args_passed
*
2
;
if
(
_length
<
(
int
)
sizeof
(
_value
.
_compact
))
{
_value
.
_compact_int
[
0
]
=
_value
.
_compact_int
[
1
]
=
_value
.
_compact_int
[
2
]
=
0
;
// Storing the signature encoded as signed chars hits about 98%
// of the time.
signed
char
*
ptr
=
_value
.
_compact
;
int
o
=
0
;
for
(
int
i
=
0
;
i
<
total_args_passed
;
i
++
)
{
VMRegPair
pair
=
regs
[
i
];
intptr_t
v1
=
pair
.
first
()
->
value
();
intptr_t
v2
=
pair
.
second
()
->
value
();
if
(
v1
==
(
signed
char
)
v1
&&
v2
==
(
signed
char
)
v2
)
{
_value
.
_compact
[
o
++
]
=
v1
;
_value
.
_compact
[
o
++
]
=
v2
;
}
else
{
goto
big
;
}
}
_length
=
-
_length
;
return
;
}
big:
_value
.
_fingerprint
=
NEW_C_HEAP_ARRAY
(
intptr_t
,
_length
);
int
o
=
0
;
for
(
int
i
=
0
;
i
<
total_args_passed
;
i
++
)
{
VMRegPair
pair
=
regs
[
i
];
intptr_t
v1
=
pair
.
first
()
->
value
();
intptr_t
v2
=
pair
.
second
()
->
value
();
_value
.
_fingerprint
[
o
++
]
=
v1
;
_value
.
_fingerprint
[
o
++
]
=
v2
;
}
}
AdapterFingerPrint
(
AdapterFingerPrint
*
orig
)
{
_length
=
orig
->
_length
;
_value
=
orig
->
_value
;
// take ownership of any storage by destroying the length
orig
->
_length
=
0
;
}
~
AdapterFingerPrint
()
{
if
(
_length
>
0
)
{
FREE_C_HEAP_ARRAY
(
int
,
_value
.
_fingerprint
);
}
}
AdapterFingerPrint
*
allocate
()
{
return
new
AdapterFingerPrint
(
this
);
}
intptr_t
value
(
int
index
)
{
if
(
_length
<
0
)
{
return
_value
.
_compact
[
index
];
}
return
_value
.
_fingerprint
[
index
];
}
int
length
()
{
if
(
_length
<
0
)
return
-
_length
;
return
_length
;
}
bool
is_compact
()
{
return
_length
<=
0
;
}
unsigned
int
compute_hash
()
{
intptr_t
hash
=
0
;
for
(
int
i
=
0
;
i
<
length
();
i
++
)
{
intptr_t
v
=
value
(
i
);
hash
=
(
hash
<<
8
)
^
v
^
(
hash
>>
5
);
}
return
(
unsigned
int
)
hash
;
}
const
char
*
as_string
()
{
stringStream
st
;
for
(
int
i
=
0
;
i
<
length
();
i
++
)
{
st
.
print
(
PTR_FORMAT
,
value
(
i
));
}
return
st
.
as_string
();
}
bool
equals
(
AdapterFingerPrint
*
other
)
{
if
(
other
->
_length
!=
_length
)
{
return
false
;
}
if
(
_length
<
0
)
{
return
_value
.
_compact_int
[
0
]
==
other
->
_value
.
_compact_int
[
0
]
&&
_value
.
_compact_int
[
1
]
==
other
->
_value
.
_compact_int
[
1
]
&&
_value
.
_compact_int
[
2
]
==
other
->
_value
.
_compact_int
[
2
];
}
else
{
for
(
int
i
=
0
;
i
<
_length
;
i
++
)
{
if
(
_value
.
_fingerprint
[
i
]
!=
other
->
_value
.
_fingerprint
[
i
])
{
return
false
;
}
}
}
return
true
;
}
};
// A hashtable mapping from AdapterFingerPrints to AdapterHandlerEntries
class
AdapterHandlerTable
:
public
BasicHashtable
{
friend
class
AdapterHandlerTableIterator
;
private:
#ifdef ASSERT
static
int
_lookups
;
// number of calls to lookup
static
int
_buckets
;
// number of buckets checked
static
int
_equals
;
// number of buckets checked with matching hash
static
int
_hits
;
// number of successful lookups
static
int
_compact
;
// number of equals calls with compact signature
#endif
AdapterHandlerEntry
*
bucket
(
int
i
)
{
return
(
AdapterHandlerEntry
*
)
BasicHashtable
::
bucket
(
i
);
}
public:
AdapterHandlerTable
()
:
BasicHashtable
(
293
,
sizeof
(
AdapterHandlerEntry
))
{
}
// Create a new entry suitable for insertion in the table
AdapterHandlerEntry
*
new_entry
(
AdapterFingerPrint
*
fingerprint
,
address
i2c_entry
,
address
c2i_entry
,
address
c2i_unverified_entry
)
{
AdapterHandlerEntry
*
entry
=
(
AdapterHandlerEntry
*
)
BasicHashtable
::
new_entry
(
fingerprint
->
compute_hash
());
entry
->
init
(
fingerprint
,
i2c_entry
,
c2i_entry
,
c2i_unverified_entry
);
return
entry
;
}
// Insert an entry into the table
void
add
(
AdapterHandlerEntry
*
entry
)
{
int
index
=
hash_to_index
(
entry
->
hash
());
add_entry
(
index
,
entry
);
}
// Find a entry with the same fingerprint if it exists
AdapterHandlerEntry
*
lookup
(
int
total_args_passed
,
VMRegPair
*
regs
)
{
debug_only
(
_lookups
++
);
AdapterFingerPrint
fp
(
total_args_passed
,
regs
);
unsigned
int
hash
=
fp
.
compute_hash
();
int
index
=
hash_to_index
(
hash
);
for
(
AdapterHandlerEntry
*
e
=
bucket
(
index
);
e
!=
NULL
;
e
=
e
->
next
())
{
debug_only
(
_buckets
++
);
if
(
e
->
hash
()
==
hash
)
{
debug_only
(
_equals
++
);
if
(
fp
.
equals
(
e
->
fingerprint
()))
{
#ifdef ASSERT
if
(
fp
.
is_compact
())
_compact
++
;
_hits
++
;
#endif
return
e
;
}
}
}
return
NULL
;
}
void
print_statistics
()
{
ResourceMark
rm
;
int
longest
=
0
;
int
empty
=
0
;
int
total
=
0
;
int
nonempty
=
0
;
for
(
int
index
=
0
;
index
<
table_size
();
index
++
)
{
int
count
=
0
;
for
(
AdapterHandlerEntry
*
e
=
bucket
(
index
);
e
!=
NULL
;
e
=
e
->
next
())
{
count
++
;
}
if
(
count
!=
0
)
nonempty
++
;
if
(
count
==
0
)
empty
++
;
if
(
count
>
longest
)
longest
=
count
;
total
+=
count
;
}
tty
->
print_cr
(
"AdapterHandlerTable: empty %d longest %d total %d average %f"
,
empty
,
longest
,
total
,
total
/
(
double
)
nonempty
);
#ifdef ASSERT
tty
->
print_cr
(
"AdapterHandlerTable: lookups %d buckets %d equals %d hits %d compact %d"
,
_lookups
,
_buckets
,
_equals
,
_hits
,
_compact
);
#endif
}
};
#ifdef ASSERT
int
AdapterHandlerTable
::
_lookups
;
int
AdapterHandlerTable
::
_buckets
;
int
AdapterHandlerTable
::
_equals
;
int
AdapterHandlerTable
::
_hits
;
int
AdapterHandlerTable
::
_compact
;
class
AdapterHandlerTableIterator
:
public
StackObj
{
private:
AdapterHandlerTable
*
_table
;
int
_index
;
AdapterHandlerEntry
*
_current
;
void
scan
()
{
while
(
_index
<
_table
->
table_size
())
{
AdapterHandlerEntry
*
a
=
_table
->
bucket
(
_index
);
if
(
a
!=
NULL
)
{
_current
=
a
;
return
;
}
_index
++
;
}
}
public:
AdapterHandlerTableIterator
(
AdapterHandlerTable
*
table
)
:
_table
(
table
),
_index
(
0
),
_current
(
NULL
)
{
scan
();
}
bool
has_next
()
{
return
_current
!=
NULL
;
}
AdapterHandlerEntry
*
next
()
{
if
(
_current
!=
NULL
)
{
AdapterHandlerEntry
*
result
=
_current
;
_current
=
_current
->
next
();
if
(
_current
==
NULL
)
scan
();
return
result
;
}
else
{
return
NULL
;
}
}
};
#endif
// ---------------------------------------------------------------------------
// Implementation of AdapterHandlerLibrary
const
char
*
AdapterHandlerEntry
::
name
=
"I2C/C2I adapters"
;
GrowableArray
<
uint64_t
>*
AdapterHandlerLibrary
::
_fingerprint
s
=
NULL
;
GrowableArray
<
AdapterHandlerEntry
*
>*
AdapterHandlerLibrary
::
_handlers
=
NULL
;
AdapterHandlerTable
*
AdapterHandlerLibrary
::
_adapter
s
=
NULL
;
AdapterHandlerEntry
*
AdapterHandlerLibrary
::
_abstract_method_handler
=
NULL
;
const
int
AdapterHandlerLibrary_size
=
16
*
K
;
BufferBlob
*
AdapterHandlerLibrary
::
_buffer
=
NULL
;
...
...
@@ -1796,28 +2045,31 @@ BufferBlob* AdapterHandlerLibrary::buffer_blob() {
}
void
AdapterHandlerLibrary
::
initialize
()
{
if
(
_fingerprints
!=
NULL
)
return
;
_fingerprints
=
new
(
ResourceObj
::
C_HEAP
)
GrowableArray
<
uint64_t
>
(
32
,
true
);
_handlers
=
new
(
ResourceObj
::
C_HEAP
)
GrowableArray
<
AdapterHandlerEntry
*>
(
32
,
true
);
// Index 0 reserved for the slow path handler
_fingerprints
->
append
(
0
/*the never-allowed 0 fingerprint*/
);
_handlers
->
append
(
NULL
);
if
(
_adapters
!=
NULL
)
return
;
_adapters
=
new
AdapterHandlerTable
();
// Create a special handler for abstract methods. Abstract methods
// are never compiled so an i2c entry is somewhat meaningless, but
// fill it in with something appropriate just in case. Pass handle
// wrong method for the c2i transitions.
address
wrong_method
=
SharedRuntime
::
get_handle_wrong_method_stub
();
_fingerprints
->
append
(
0
/*the never-allowed 0 fingerprint*/
);
assert
(
_handlers
->
length
()
==
AbstractMethodHandler
,
"in wrong slot"
);
_handlers
->
append
(
new
AdapterHandlerEntry
(
StubRoutines
::
throw_AbstractMethodError_entry
(),
wrong_method
,
wrong_method
));
_abstract_method_handler
=
AdapterHandlerLibrary
::
new_entry
(
new
AdapterFingerPrint
(
0
,
NULL
),
StubRoutines
::
throw_AbstractMethodError_entry
(),
wrong_method
,
wrong_method
);
}
AdapterHandlerEntry
*
AdapterHandlerLibrary
::
new_entry
(
AdapterFingerPrint
*
fingerprint
,
address
i2c_entry
,
address
c2i_entry
,
address
c2i_unverified_entry
)
{
return
_adapters
->
new_entry
(
fingerprint
,
i2c_entry
,
c2i_entry
,
c2i_unverified_entry
);
}
int
AdapterHandlerLibrary
::
get_create_adapter_index
(
methodHandle
method
)
{
// Use customized signature handler. Need to lock around updates to the
// _fingerprints array (it is not safe for concurrent readers and a single
// writer: this can be fixed if it becomes a problem).
AdapterHandlerEntry
*
AdapterHandlerLibrary
::
get_adapter
(
methodHandle
method
)
{
// Use customized signature handler. Need to lock around updates to
// the AdapterHandlerTable (it is not safe for concurrent readers
// and a single writer: this could be fixed if it becomes a
// problem).
// Get the address of the ic_miss handlers before we grab the
// AdapterHandlerLibrary_lock. This fixes bug 6236259 which
...
...
@@ -1828,47 +2080,49 @@ int AdapterHandlerLibrary::get_create_adapter_index(methodHandle method) {
address
ic_miss
=
SharedRuntime
::
get_ic_miss_stub
();
assert
(
ic_miss
!=
NULL
,
"must have handler"
);
int
result
;
ResourceMark
rm
;
NOT_PRODUCT
(
int
code_size
);
BufferBlob
*
B
=
NULL
;
AdapterHandlerEntry
*
entry
=
NULL
;
uint64_t
fingerprint
;
AdapterFingerPrint
*
fingerprint
=
NULL
;
{
MutexLocker
mu
(
AdapterHandlerLibrary_lock
);
// make sure data structure is initialized
initialize
();
if
(
method
->
is_abstract
())
{
return
AbstractMethodH
andler
;
return
_abstract_method_h
andler
;
}
// Fill in the signature array, for the calling-convention call.
int
total_args_passed
=
method
->
size_of_parameters
();
// All args on stack
BasicType
*
sig_bt
=
NEW_RESOURCE_ARRAY
(
BasicType
,
total_args_passed
);
VMRegPair
*
regs
=
NEW_RESOURCE_ARRAY
(
VMRegPair
,
total_args_passed
);
int
i
=
0
;
if
(
!
method
->
is_static
())
// Pass in receiver first
sig_bt
[
i
++
]
=
T_OBJECT
;
for
(
SignatureStream
ss
(
method
->
signature
());
!
ss
.
at_return_type
();
ss
.
next
())
{
sig_bt
[
i
++
]
=
ss
.
type
();
// Collect remaining bits of signature
if
(
ss
.
type
()
==
T_LONG
||
ss
.
type
()
==
T_DOUBLE
)
sig_bt
[
i
++
]
=
T_VOID
;
// Longs & doubles take 2 Java slots
}
assert
(
i
==
total_args_passed
,
""
);
// Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage
int
comp_args_on_stack
=
SharedRuntime
::
java_calling_convention
(
sig_bt
,
regs
,
total_args_passed
,
false
);
// Lookup method signature's fingerprint
fingerprint
=
Fingerprinter
(
method
).
fingerprint
();
assert
(
fingerprint
!=
CONST64
(
0
),
"no zero fingerprints allowed"
);
// Fingerprints are small fixed-size condensed representations of
// signatures. If the signature is too large, it won't fit in a
// fingerprint. Signatures which cannot support a fingerprint get a new i2c
// adapter gen'd each time, instead of searching the cache for one. This -1
// game can be avoided if I compared signatures instead of using
// fingerprints. However, -1 fingerprints are very rare.
if
(
fingerprint
!=
UCONST64
(
-
1
)
)
{
// If this is a cache-able fingerprint
// Turns out i2c adapters do not care what the return value is. Mask it
// out so signatures that only differ in return type will share the same
// adapter.
fingerprint
&=
~
(
SignatureIterator
::
result_feature_mask
<<
SignatureIterator
::
static_feature_size
);
// Search for a prior existing i2c/c2i adapter
int
index
=
_fingerprints
->
find
(
fingerprint
);
if
(
index
>=
0
)
return
index
;
// Found existing handlers?
}
else
{
// Annoyingly, I end up adding -1 fingerprints to the array of handlers,
// because I need a unique handler index. It cannot be scanned for
// because all -1's look alike. Instead, the matching index is passed out
// and immediately used to collect the 2 return values (the c2i and i2c
// adapters).
entry
=
_adapters
->
lookup
(
total_args_passed
,
regs
);
if
(
entry
!=
NULL
)
{
return
entry
;
}
// Make a C heap allocated version of the fingerprint to store in the adapter
fingerprint
=
new
AdapterFingerPrint
(
total_args_passed
,
regs
);
// Create I2C & C2I handlers
ResourceMark
rm
;
BufferBlob
*
buf
=
buffer_blob
();
// the temporary code buffer in CodeCache
if
(
buf
!=
NULL
)
{
...
...
@@ -1878,32 +2132,12 @@ int AdapterHandlerLibrary::get_create_adapter_index(methodHandle method) {
sizeof
(
buffer_locs
)
/
sizeof
(
relocInfo
));
MacroAssembler
_masm
(
&
buffer
);
// Fill in the signature array, for the calling-convention call.
int
total_args_passed
=
method
->
size_of_parameters
();
// All args on stack
BasicType
*
sig_bt
=
NEW_RESOURCE_ARRAY
(
BasicType
,
total_args_passed
);
VMRegPair
*
regs
=
NEW_RESOURCE_ARRAY
(
VMRegPair
,
total_args_passed
);
int
i
=
0
;
if
(
!
method
->
is_static
()
)
// Pass in receiver first
sig_bt
[
i
++
]
=
T_OBJECT
;
for
(
SignatureStream
ss
(
method
->
signature
());
!
ss
.
at_return_type
();
ss
.
next
())
{
sig_bt
[
i
++
]
=
ss
.
type
();
// Collect remaining bits of signature
if
(
ss
.
type
()
==
T_LONG
||
ss
.
type
()
==
T_DOUBLE
)
sig_bt
[
i
++
]
=
T_VOID
;
// Longs & doubles take 2 Java slots
}
assert
(
i
==
total_args_passed
,
""
);
// Now get the re-packed compiled-Java layout.
int
comp_args_on_stack
;
// Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage
comp_args_on_stack
=
SharedRuntime
::
java_calling_convention
(
sig_bt
,
regs
,
total_args_passed
,
false
);
entry
=
SharedRuntime
::
generate_i2c2i_adapters
(
&
_masm
,
total_args_passed
,
comp_args_on_stack
,
sig_bt
,
regs
);
regs
,
fingerprint
);
B
=
BufferBlob
::
create
(
AdapterHandlerEntry
::
name
,
&
buffer
);
NOT_PRODUCT
(
code_size
=
buffer
.
code_size
());
...
...
@@ -1925,36 +2159,31 @@ int AdapterHandlerLibrary::get_create_adapter_index(methodHandle method) {
UseCompiler
=
false
;
AlwaysCompileLoopMethods
=
false
;
}
return
0
;
// Out of CodeCache space (_handlers[0] == NULL)
return
NULL
;
// Out of CodeCache space
}
entry
->
relocate
(
B
->
instructions_begin
());
#ifndef PRODUCT
// debugging suppport
if
(
PrintAdapterHandlers
)
{
tty
->
cr
();
tty
->
print_cr
(
"i2c argument handler #%d for: %s %s (fingerprint =
0x%llx
, %d bytes generated)"
,
_
handlers
->
length
(),
(
method
->
is_static
()
?
"static"
:
"receiver"
),
method
->
signature
()
->
as_C_string
(),
fingerprint
,
code_size
);
tty
->
print_cr
(
"i2c argument handler #%d for: %s %s (fingerprint =
%s
, %d bytes generated)"
,
_
adapters
->
number_of_entries
(),
(
method
->
is_static
()
?
"static"
:
"receiver"
),
method
->
signature
()
->
as_C_string
(),
fingerprint
->
as_string
()
,
code_size
);
tty
->
print_cr
(
"c2i argument handler starts at %p"
,
entry
->
get_c2i_entry
());
Disassembler
::
decode
(
entry
->
get_i2c_entry
(),
entry
->
get_i2c_entry
()
+
code_size
);
}
#endif
// add handlers to library
_fingerprints
->
append
(
fingerprint
);
_handlers
->
append
(
entry
);
// set handler index
assert
(
_fingerprints
->
length
()
==
_handlers
->
length
(),
"sanity check"
);
result
=
_fingerprints
->
length
()
-
1
;
_adapters
->
add
(
entry
);
}
// Outside of the lock
if
(
B
!=
NULL
)
{
char
blob_id
[
256
];
jio_snprintf
(
blob_id
,
sizeof
(
blob_id
),
"%s(
"
PTR64_FORMAT
"
)@"
PTR_FORMAT
,
"%s(
%s
)@"
PTR_FORMAT
,
AdapterHandlerEntry
::
name
,
fingerprint
,
fingerprint
->
as_string
()
,
B
->
instructions_begin
());
VTune
::
register_stub
(
blob_id
,
B
->
instructions_begin
(),
B
->
instructions_end
());
Forte
::
register_stub
(
blob_id
,
B
->
instructions_begin
(),
B
->
instructions_end
());
...
...
@@ -1965,7 +2194,7 @@ int AdapterHandlerLibrary::get_create_adapter_index(methodHandle method) {
B
->
instructions_end
());
}
}
return
result
;
return
entry
;
}
void
AdapterHandlerEntry
::
relocate
(
address
new_base
)
{
...
...
@@ -2308,30 +2537,31 @@ JRT_END
#ifndef PRODUCT
bool
AdapterHandlerLibrary
::
contains
(
CodeBlob
*
b
)
{
if
(
_handlers
==
NULL
)
return
false
;
for
(
int
i
=
0
;
i
<
_handlers
->
length
()
;
i
++
)
{
AdapterHandlerEntry
*
a
=
get_entry
(
i
);
if
(
a
!=
NULL
&&
b
==
CodeCache
::
find_blob
(
a
->
get_i2c_entry
())
)
return
true
;
AdapterHandlerTableIterator
iter
(
_adapters
);
while
(
iter
.
has_next
())
{
AdapterHandlerEntry
*
a
=
iter
.
next
();
if
(
b
==
CodeCache
::
find_blob
(
a
->
get_i2c_entry
())
)
return
true
;
}
return
false
;
}
void
AdapterHandlerLibrary
::
print_handler
(
CodeBlob
*
b
)
{
for
(
int
i
=
0
;
i
<
_handlers
->
length
()
;
i
++
)
{
AdapterHandlerEntry
*
a
=
get_entry
(
i
);
if
(
a
!=
NULL
&&
b
==
CodeCache
::
find_blob
(
a
->
get_i2c_entry
())
)
{
AdapterHandlerTableIterator
iter
(
_adapters
);
while
(
iter
.
has_next
()
)
{
AdapterHandlerEntry
*
a
=
iter
.
next
(
);
if
(
b
==
CodeCache
::
find_blob
(
a
->
get_i2c_entry
())
)
{
tty
->
print
(
"Adapter for signature: "
);
// Fingerprinter::print(_fingerprints->at(i));
tty
->
print
(
"0x%"
FORMAT64_MODIFIER
"x"
,
_fingerprints
->
at
(
i
));
tty
->
print_cr
(
" i2c: "
INTPTR_FORMAT
" c2i: "
INTPTR_FORMAT
" c2iUV: "
INTPTR_FORMAT
,
tty
->
print_cr
(
"%s i2c: "
INTPTR_FORMAT
" c2i: "
INTPTR_FORMAT
" c2iUV: "
INTPTR_FORMAT
,
a
->
fingerprint
()
->
as_string
(),
a
->
get_i2c_entry
(),
a
->
get_c2i_entry
(),
a
->
get_c2i_unverified_entry
());
return
;
}
}
assert
(
false
,
"Should have found handler"
);
}
void
AdapterHandlerLibrary
::
print_statistics
()
{
_adapters
->
print_statistics
();
}
#endif
/* PRODUCT */
src/share/vm/runtime/sharedRuntime.hpp
浏览文件 @
9ae3a3cd
/*
* Copyright 1997-20
09
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-20
10
Sun Microsystems, Inc. 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
...
...
@@ -23,6 +23,8 @@
*/
class
AdapterHandlerEntry
;
class
AdapterHandlerTable
;
class
AdapterFingerPrint
;
class
vframeStream
;
// Runtime is the base class for various runtime interfaces
...
...
@@ -337,7 +339,8 @@ class SharedRuntime: AllStatic {
int
total_args_passed
,
int
max_arg
,
const
BasicType
*
sig_bt
,
const
VMRegPair
*
regs
);
const
VMRegPair
*
regs
,
AdapterFingerPrint
*
fingerprint
);
// OSR support
...
...
@@ -528,28 +531,41 @@ class SharedRuntime: AllStatic {
// used by the adapters. The code generation happens here because it's very
// similar to what the adapters have to do.
class
AdapterHandlerEntry
:
public
CHeapObj
{
class
AdapterHandlerEntry
:
public
BasicHashtableEntry
{
friend
class
AdapterHandlerTable
;
private:
AdapterFingerPrint
*
_fingerprint
;
address
_i2c_entry
;
address
_c2i_entry
;
address
_c2i_unverified_entry
;
public:
void
init
(
AdapterFingerPrint
*
fingerprint
,
address
i2c_entry
,
address
c2i_entry
,
address
c2i_unverified_entry
)
{
_fingerprint
=
fingerprint
;
_i2c_entry
=
i2c_entry
;
_c2i_entry
=
c2i_entry
;
_c2i_unverified_entry
=
c2i_unverified_entry
;
}
// should never be used
AdapterHandlerEntry
();
public:
// The name we give all buffer blobs
static
const
char
*
name
;
AdapterHandlerEntry
(
address
i2c_entry
,
address
c2i_entry
,
address
c2i_unverified_entry
)
:
_i2c_entry
(
i2c_entry
),
_c2i_entry
(
c2i_entry
),
_c2i_unverified_entry
(
c2i_unverified_entry
)
{
}
address
get_i2c_entry
()
{
return
_i2c_entry
;
}
address
get_c2i_entry
()
{
return
_c2i_entry
;
}
address
get_c2i_unverified_entry
()
{
return
_c2i_unverified_entry
;
}
void
relocate
(
address
new_base
);
AdapterFingerPrint
*
fingerprint
()
{
return
_fingerprint
;
}
AdapterHandlerEntry
*
next
()
{
return
(
AdapterHandlerEntry
*
)
BasicHashtableEntry
::
next
();
}
#ifndef PRODUCT
void
print
();
#endif
/* PRODUCT */
...
...
@@ -558,30 +574,18 @@ class AdapterHandlerEntry : public CHeapObj {
class
AdapterHandlerLibrary
:
public
AllStatic
{
private:
static
BufferBlob
*
_buffer
;
// the temporary code buffer in CodeCache
static
GrowableArray
<
uint64_t
>*
_fingerprints
;
// the fingerprint collection
static
GrowableArray
<
AdapterHandlerEntry
*>
*
_handlers
;
// the corresponding handlers
enum
{
AbstractMethodHandler
=
1
// special handler for abstract methods
};
static
AdapterHandlerTable
*
_adapters
;
static
AdapterHandlerEntry
*
_abstract_method_handler
;
static
BufferBlob
*
buffer_blob
();
static
void
initialize
();
static
int
get_create_adapter_index
(
methodHandle
method
);
static
address
get_i2c_entry
(
int
index
)
{
return
get_entry
(
index
)
->
get_i2c_entry
();
}
static
address
get_c2i_entry
(
int
index
)
{
return
get_entry
(
index
)
->
get_c2i_entry
();
}
static
address
get_c2i_unverified_entry
(
int
index
)
{
return
get_entry
(
index
)
->
get_c2i_unverified_entry
();
}
public:
static
AdapterHandlerEntry
*
get_entry
(
int
index
)
{
return
_handlers
->
at
(
index
);
}
static
AdapterHandlerEntry
*
new_entry
(
AdapterFingerPrint
*
fingerprint
,
address
i2c_entry
,
address
c2i_entry
,
address
c2i_unverified_entry
);
static
nmethod
*
create_native_wrapper
(
methodHandle
method
);
static
AdapterHandlerEntry
*
get_adapter
(
methodHandle
method
)
{
return
get_entry
(
get_create_adapter_index
(
method
));
}
static
AdapterHandlerEntry
*
get_adapter
(
methodHandle
method
);
#ifdef HAVE_DTRACE_H
static
nmethod
*
create_dtrace_nmethod
(
methodHandle
method
);
#endif // HAVE_DTRACE_H
...
...
@@ -589,6 +593,7 @@ class AdapterHandlerLibrary: public AllStatic {
#ifndef PRODUCT
static
void
print_handler
(
CodeBlob
*
b
);
static
bool
contains
(
CodeBlob
*
b
);
static
void
print_statistics
();
#endif
/* PRODUCT */
};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录