mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
Merge
This commit is contained in:
commit
402fd01231
94 changed files with 917 additions and 675 deletions
1
.hgtags
1
.hgtags
|
@ -180,3 +180,4 @@ c7aa5cca1c01689a7b1a92411daf83684af05a33 jdk8-b53
|
||||||
ffe6bce5a521be40146af2ac03c509b7bac30595 jdk8-b56
|
ffe6bce5a521be40146af2ac03c509b7bac30595 jdk8-b56
|
||||||
2c21c080b11b93efb3851e39e1363e45da805943 jdk8-b57
|
2c21c080b11b93efb3851e39e1363e45da805943 jdk8-b57
|
||||||
479d3302a26d7607ba271d66973e59ebf58825b6 jdk8-b58
|
479d3302a26d7607ba271d66973e59ebf58825b6 jdk8-b58
|
||||||
|
3bd874584fc01aae92fbc8827e2bd04d8b6ace04 jdk8-b59
|
||||||
|
|
|
@ -180,3 +180,4 @@ b85b44cced2406792cfb9baab1377ff03e7001d8 jdk8-b55
|
||||||
76844579fa4b30929731115b237e477181a82394 jdk8-b56
|
76844579fa4b30929731115b237e477181a82394 jdk8-b56
|
||||||
522dfac8ca4d07c0b74025d4ac3b6e5feefbb829 jdk8-b57
|
522dfac8ca4d07c0b74025d4ac3b6e5feefbb829 jdk8-b57
|
||||||
9367024804874faf8e958adeb333682bab1c0c47 jdk8-b58
|
9367024804874faf8e958adeb333682bab1c0c47 jdk8-b58
|
||||||
|
dae9821589ccd2611bdf7084269b98e819091770 jdk8-b59
|
||||||
|
|
|
@ -180,3 +180,4 @@ e8a0e84383d6fbd303ce44bd355fb25972b13286 jdk8-b55
|
||||||
bf1bb47414e178beff67dc255fc3b97bf401f679 jdk8-b56
|
bf1bb47414e178beff67dc255fc3b97bf401f679 jdk8-b56
|
||||||
f3ab4163ae012965fc8acdfc25ce0fece8d6906d jdk8-b57
|
f3ab4163ae012965fc8acdfc25ce0fece8d6906d jdk8-b57
|
||||||
18462a19f7bd66d38015f61ea549a5e0c0c889a3 jdk8-b58
|
18462a19f7bd66d38015f61ea549a5e0c0c889a3 jdk8-b58
|
||||||
|
d54dc53e223ed9ce7d5f4d2cd02ad9d5def3c2db jdk8-b59
|
||||||
|
|
|
@ -282,3 +282,5 @@ d70102c4cb73158902acaa6016f47c7bc14e0d67 jdk8-b57
|
||||||
6bb378c50828e9d76fb2653d1712c66ea8fc47db jdk8-b58
|
6bb378c50828e9d76fb2653d1712c66ea8fc47db jdk8-b58
|
||||||
f2e12eb74117c917c0bb264694c02de4a6a15a10 hs25-b03
|
f2e12eb74117c917c0bb264694c02de4a6a15a10 hs25-b03
|
||||||
8a1a6b9b4f20fd2f6a12441d638e51f19a82db19 jdk8-b59
|
8a1a6b9b4f20fd2f6a12441d638e51f19a82db19 jdk8-b59
|
||||||
|
1cc7a2a11d00832e3d07f81f3744a6883422db7e hs25-b04
|
||||||
|
3cfd05b2219a29649741a52637696f06acf24a4e jdk8-b60
|
||||||
|
|
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2012
|
||||||
|
|
||||||
HS_MAJOR_VER=25
|
HS_MAJOR_VER=25
|
||||||
HS_MINOR_VER=0
|
HS_MINOR_VER=0
|
||||||
HS_BUILD_NUMBER=03
|
HS_BUILD_NUMBER=04
|
||||||
|
|
||||||
JDK_MAJOR_VER=1
|
JDK_MAJOR_VER=1
|
||||||
JDK_MINOR_VER=8
|
JDK_MINOR_VER=8
|
||||||
|
|
|
@ -1870,6 +1870,11 @@ const int Matcher::vector_ideal_reg(int size) {
|
||||||
return Op_RegD;
|
return Op_RegD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int Matcher::vector_shift_count_ideal_reg(int size) {
|
||||||
|
fatal("vector shift is not supported");
|
||||||
|
return Node::NotAMachineReg;
|
||||||
|
}
|
||||||
|
|
||||||
// Limits on vector size (number of elements) loaded into vector.
|
// Limits on vector size (number of elements) loaded into vector.
|
||||||
const int Matcher::max_vector_size(const BasicType bt) {
|
const int Matcher::max_vector_size(const BasicType bt) {
|
||||||
assert(is_java_primitive(bt), "only primitive type vectors");
|
assert(is_java_primitive(bt), "only primitive type vectors");
|
||||||
|
|
|
@ -2936,6 +2936,7 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||||
// Push the appendix as a trailing parameter.
|
// Push the appendix as a trailing parameter.
|
||||||
// This must be done before we get the receiver,
|
// This must be done before we get the receiver,
|
||||||
// since the parameter_size includes it.
|
// since the parameter_size includes it.
|
||||||
|
assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
|
||||||
__ load_resolved_reference_at_index(temp, index);
|
__ load_resolved_reference_at_index(temp, index);
|
||||||
__ verify_oop(temp);
|
__ verify_oop(temp);
|
||||||
__ push_ptr(temp); // push appendix (MethodType, CallSite, etc.)
|
__ push_ptr(temp); // push appendix (MethodType, CallSite, etc.)
|
||||||
|
@ -3235,15 +3236,15 @@ void TemplateTable::invokehandle(int byte_no) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Register Rret = Lscratch;
|
const Register Rret = Lscratch;
|
||||||
const Register G4_mtype = G4_scratch; // f1
|
const Register G4_mtype = G4_scratch;
|
||||||
const Register O0_recv = O0;
|
const Register O0_recv = O0;
|
||||||
const Register Rscratch = G3_scratch;
|
const Register Rscratch = G3_scratch;
|
||||||
|
|
||||||
prepare_invoke(byte_no, G5_method, Rret, G4_mtype, O0_recv);
|
prepare_invoke(byte_no, G5_method, Rret, G4_mtype, O0_recv);
|
||||||
__ null_check(O0_recv);
|
__ null_check(O0_recv);
|
||||||
|
|
||||||
// G4: MethodType object (from cpool->resolved_references[])
|
// G4: MethodType object (from cpool->resolved_references[f1], if necessary)
|
||||||
// G5: MH.linkToCallSite method (from f2)
|
// G5: MH.invokeExact_MT method (from f2)
|
||||||
|
|
||||||
// Note: G4_mtype is already pushed (if necessary) by prepare_invoke
|
// Note: G4_mtype is already pushed (if necessary) by prepare_invoke
|
||||||
|
|
||||||
|
@ -3275,8 +3276,8 @@ void TemplateTable::invokedynamic(int byte_no) {
|
||||||
|
|
||||||
prepare_invoke(byte_no, G5_method, Rret, G4_callsite);
|
prepare_invoke(byte_no, G5_method, Rret, G4_callsite);
|
||||||
|
|
||||||
// G4: CallSite object (from cpool->resolved_references[])
|
// G4: CallSite object (from cpool->resolved_references[f1])
|
||||||
// G5: MH.linkToCallSite method (from f1)
|
// G5: MH.linkToCallSite method (from f2)
|
||||||
|
|
||||||
// Note: G4_callsite is already pushed by prepare_invoke
|
// Note: G4_callsite is already pushed by prepare_invoke
|
||||||
|
|
||||||
|
|
|
@ -2139,7 +2139,7 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
|
||||||
const int index_offset = in_bytes(ConstantPoolCache::base_offset() +
|
const int index_offset = in_bytes(ConstantPoolCache::base_offset() +
|
||||||
ConstantPoolCacheEntry::f2_offset());
|
ConstantPoolCacheEntry::f2_offset());
|
||||||
|
|
||||||
size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2));
|
size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2));
|
||||||
resolve_cache_and_index(byte_no, cache, index, index_size);
|
resolve_cache_and_index(byte_no, cache, index, index_size);
|
||||||
__ movptr(method, Address(cache, index, Address::times_ptr, method_offset));
|
__ movptr(method, Address(cache, index, Address::times_ptr, method_offset));
|
||||||
|
|
||||||
|
@ -2876,6 +2876,7 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||||
// since the parameter_size includes it.
|
// since the parameter_size includes it.
|
||||||
__ push(rbx);
|
__ push(rbx);
|
||||||
__ mov(rbx, index);
|
__ mov(rbx, index);
|
||||||
|
assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
|
||||||
__ load_resolved_reference_at_index(index, rbx);
|
__ load_resolved_reference_at_index(index, rbx);
|
||||||
__ pop(rbx);
|
__ pop(rbx);
|
||||||
__ push(index); // push appendix (MethodType, CallSite, etc.)
|
__ push(index); // push appendix (MethodType, CallSite, etc.)
|
||||||
|
@ -3093,8 +3094,8 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||||
void TemplateTable::invokehandle(int byte_no) {
|
void TemplateTable::invokehandle(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");
|
||||||
const Register rbx_method = rbx; // (from f2)
|
const Register rbx_method = rbx;
|
||||||
const Register rax_mtype = rax; // (from f1)
|
const Register rax_mtype = rax;
|
||||||
const Register rcx_recv = rcx;
|
const Register rcx_recv = rcx;
|
||||||
const Register rdx_flags = rdx;
|
const Register rdx_flags = rdx;
|
||||||
|
|
||||||
|
@ -3104,13 +3105,14 @@ void TemplateTable::invokehandle(int byte_no) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_invoke(byte_no,
|
prepare_invoke(byte_no, rbx_method, rax_mtype, rcx_recv);
|
||||||
rbx_method, rax_mtype, // get f2 Method*, f1 MethodType
|
|
||||||
rcx_recv);
|
|
||||||
__ verify_method_ptr(rbx_method);
|
__ verify_method_ptr(rbx_method);
|
||||||
__ verify_oop(rcx_recv);
|
__ verify_oop(rcx_recv);
|
||||||
__ null_check(rcx_recv);
|
__ null_check(rcx_recv);
|
||||||
|
|
||||||
|
// rax: MethodType object (from cpool->resolved_references[f1], if necessary)
|
||||||
|
// rbx: MH.invokeExact_MT method (from f2)
|
||||||
|
|
||||||
// Note: rax_mtype is already pushed (if necessary) by prepare_invoke
|
// Note: rax_mtype is already pushed (if necessary) by prepare_invoke
|
||||||
|
|
||||||
// FIXME: profile the LambdaForm also
|
// FIXME: profile the LambdaForm also
|
||||||
|
@ -3140,7 +3142,7 @@ void TemplateTable::invokedynamic(int byte_no) {
|
||||||
|
|
||||||
prepare_invoke(byte_no, rbx_method, rax_callsite);
|
prepare_invoke(byte_no, rbx_method, rax_callsite);
|
||||||
|
|
||||||
// rax: CallSite object (from cpool->resolved_references[])
|
// rax: CallSite object (from cpool->resolved_references[f1])
|
||||||
// rbx: MH.linkToCallSite method (from f2)
|
// rbx: MH.linkToCallSite method (from f2)
|
||||||
|
|
||||||
// Note: rax_callsite is already pushed by prepare_invoke
|
// Note: rax_callsite is already pushed by prepare_invoke
|
||||||
|
|
|
@ -2184,7 +2184,7 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
|
||||||
const int index_offset = in_bytes(ConstantPoolCache::base_offset() +
|
const int index_offset = in_bytes(ConstantPoolCache::base_offset() +
|
||||||
ConstantPoolCacheEntry::f2_offset());
|
ConstantPoolCacheEntry::f2_offset());
|
||||||
|
|
||||||
size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2));
|
size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2));
|
||||||
resolve_cache_and_index(byte_no, cache, index, index_size);
|
resolve_cache_and_index(byte_no, cache, index, index_size);
|
||||||
__ movptr(method, Address(cache, index, Address::times_ptr, method_offset));
|
__ movptr(method, Address(cache, index, Address::times_ptr, method_offset));
|
||||||
|
|
||||||
|
@ -2926,6 +2926,7 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||||
// since the parameter_size includes it.
|
// since the parameter_size includes it.
|
||||||
__ push(rbx);
|
__ push(rbx);
|
||||||
__ mov(rbx, index);
|
__ mov(rbx, index);
|
||||||
|
assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
|
||||||
__ load_resolved_reference_at_index(index, rbx);
|
__ load_resolved_reference_at_index(index, rbx);
|
||||||
__ pop(rbx);
|
__ pop(rbx);
|
||||||
__ push(index); // push appendix (MethodType, CallSite, etc.)
|
__ push(index); // push appendix (MethodType, CallSite, etc.)
|
||||||
|
@ -3144,8 +3145,8 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||||
void TemplateTable::invokehandle(int byte_no) {
|
void TemplateTable::invokehandle(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");
|
||||||
const Register rbx_method = rbx; // f2
|
const Register rbx_method = rbx;
|
||||||
const Register rax_mtype = rax; // f1
|
const Register rax_mtype = rax;
|
||||||
const Register rcx_recv = rcx;
|
const Register rcx_recv = rcx;
|
||||||
const Register rdx_flags = rdx;
|
const Register rdx_flags = rdx;
|
||||||
|
|
||||||
|
@ -3155,13 +3156,14 @@ void TemplateTable::invokehandle(int byte_no) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_invoke(byte_no,
|
prepare_invoke(byte_no, rbx_method, rax_mtype, rcx_recv);
|
||||||
rbx_method, rax_mtype, // get f2 Method*, f1 MethodType
|
|
||||||
rcx_recv);
|
|
||||||
__ verify_method_ptr(rbx_method);
|
__ verify_method_ptr(rbx_method);
|
||||||
__ verify_oop(rcx_recv);
|
__ verify_oop(rcx_recv);
|
||||||
__ null_check(rcx_recv);
|
__ null_check(rcx_recv);
|
||||||
|
|
||||||
|
// rax: MethodType object (from cpool->resolved_references[f1], if necessary)
|
||||||
|
// rbx: MH.invokeExact_MT method (from f2)
|
||||||
|
|
||||||
// Note: rax_mtype is already pushed (if necessary) by prepare_invoke
|
// Note: rax_mtype is already pushed (if necessary) by prepare_invoke
|
||||||
|
|
||||||
// FIXME: profile the LambdaForm also
|
// FIXME: profile the LambdaForm also
|
||||||
|
@ -3191,7 +3193,7 @@ void TemplateTable::invokedynamic(int byte_no) {
|
||||||
|
|
||||||
prepare_invoke(byte_no, rbx_method, rax_callsite);
|
prepare_invoke(byte_no, rbx_method, rax_callsite);
|
||||||
|
|
||||||
// rax: CallSite object (from cpool->resolved_references[])
|
// rax: CallSite object (from cpool->resolved_references[f1])
|
||||||
// rbx: MH.linkToCallSite method (from f2)
|
// rbx: MH.linkToCallSite method (from f2)
|
||||||
|
|
||||||
// Note: rax_callsite is already pushed by prepare_invoke
|
// Note: rax_callsite is already pushed by prepare_invoke
|
||||||
|
|
|
@ -571,6 +571,11 @@ const int Matcher::vector_ideal_reg(int size) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only lowest bits of xmm reg are used for vector shift count.
|
||||||
|
const int Matcher::vector_shift_count_ideal_reg(int size) {
|
||||||
|
return Op_VecS;
|
||||||
|
}
|
||||||
|
|
||||||
// x86 supports misaligned vectors store/load.
|
// x86 supports misaligned vectors store/load.
|
||||||
const bool Matcher::misaligned_vectors_ok() {
|
const bool Matcher::misaligned_vectors_ok() {
|
||||||
return !AlignVector; // can be changed by flag
|
return !AlignVector; // can be changed by flag
|
||||||
|
@ -3758,10 +3763,24 @@ instruct vdiv4D_mem(vecY dst, vecY src, memory mem) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// ------------------------------ Shift ---------------------------------------
|
||||||
|
|
||||||
|
// Left and right shift count vectors are the same on x86
|
||||||
|
// (only lowest bits of xmm reg are used for count).
|
||||||
|
instruct vshiftcnt(vecS dst, rRegI cnt) %{
|
||||||
|
match(Set dst (LShiftCntV cnt));
|
||||||
|
match(Set dst (RShiftCntV cnt));
|
||||||
|
format %{ "movd $dst,$cnt\t! load shift count" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ movdl($dst$$XMMRegister, $cnt$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe( pipe_slow );
|
||||||
|
%}
|
||||||
|
|
||||||
// ------------------------------ LeftShift -----------------------------------
|
// ------------------------------ LeftShift -----------------------------------
|
||||||
|
|
||||||
// Shorts/Chars vector left shift
|
// Shorts/Chars vector left shift
|
||||||
instruct vsll2S(vecS dst, regF shift) %{
|
instruct vsll2S(vecS dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 2);
|
predicate(n->as_Vector()->length() == 2);
|
||||||
match(Set dst (LShiftVS dst shift));
|
match(Set dst (LShiftVS dst shift));
|
||||||
format %{ "psllw $dst,$shift\t! left shift packed2S" %}
|
format %{ "psllw $dst,$shift\t! left shift packed2S" %}
|
||||||
|
@ -3781,7 +3800,7 @@ instruct vsll2S_imm(vecS dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll2S_reg(vecS dst, vecS src, regF shift) %{
|
instruct vsll2S_reg(vecS dst, vecS src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
||||||
match(Set dst (LShiftVS src shift));
|
match(Set dst (LShiftVS src shift));
|
||||||
format %{ "vpsllw $dst,$src,$shift\t! left shift packed2S" %}
|
format %{ "vpsllw $dst,$src,$shift\t! left shift packed2S" %}
|
||||||
|
@ -3803,7 +3822,7 @@ instruct vsll2S_reg_imm(vecS dst, vecS src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll4S(vecD dst, regF shift) %{
|
instruct vsll4S(vecD dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 4);
|
predicate(n->as_Vector()->length() == 4);
|
||||||
match(Set dst (LShiftVS dst shift));
|
match(Set dst (LShiftVS dst shift));
|
||||||
format %{ "psllw $dst,$shift\t! left shift packed4S" %}
|
format %{ "psllw $dst,$shift\t! left shift packed4S" %}
|
||||||
|
@ -3823,7 +3842,7 @@ instruct vsll4S_imm(vecD dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll4S_reg(vecD dst, vecD src, regF shift) %{
|
instruct vsll4S_reg(vecD dst, vecD src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
|
||||||
match(Set dst (LShiftVS src shift));
|
match(Set dst (LShiftVS src shift));
|
||||||
format %{ "vpsllw $dst,$src,$shift\t! left shift packed4S" %}
|
format %{ "vpsllw $dst,$src,$shift\t! left shift packed4S" %}
|
||||||
|
@ -3845,7 +3864,7 @@ instruct vsll4S_reg_imm(vecD dst, vecD src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll8S(vecX dst, regF shift) %{
|
instruct vsll8S(vecX dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 8);
|
predicate(n->as_Vector()->length() == 8);
|
||||||
match(Set dst (LShiftVS dst shift));
|
match(Set dst (LShiftVS dst shift));
|
||||||
format %{ "psllw $dst,$shift\t! left shift packed8S" %}
|
format %{ "psllw $dst,$shift\t! left shift packed8S" %}
|
||||||
|
@ -3865,7 +3884,7 @@ instruct vsll8S_imm(vecX dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll8S_reg(vecX dst, vecX src, regF shift) %{
|
instruct vsll8S_reg(vecX dst, vecX src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
|
||||||
match(Set dst (LShiftVS src shift));
|
match(Set dst (LShiftVS src shift));
|
||||||
format %{ "vpsllw $dst,$src,$shift\t! left shift packed8S" %}
|
format %{ "vpsllw $dst,$src,$shift\t! left shift packed8S" %}
|
||||||
|
@ -3887,7 +3906,7 @@ instruct vsll8S_reg_imm(vecX dst, vecX src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll16S_reg(vecY dst, vecY src, regF shift) %{
|
instruct vsll16S_reg(vecY dst, vecY src, vecS shift) %{
|
||||||
predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
|
predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
|
||||||
match(Set dst (LShiftVS src shift));
|
match(Set dst (LShiftVS src shift));
|
||||||
format %{ "vpsllw $dst,$src,$shift\t! left shift packed16S" %}
|
format %{ "vpsllw $dst,$src,$shift\t! left shift packed16S" %}
|
||||||
|
@ -3910,7 +3929,7 @@ instruct vsll16S_reg_imm(vecY dst, vecY src, immI8 shift) %{
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Integers vector left shift
|
// Integers vector left shift
|
||||||
instruct vsll2I(vecD dst, regF shift) %{
|
instruct vsll2I(vecD dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 2);
|
predicate(n->as_Vector()->length() == 2);
|
||||||
match(Set dst (LShiftVI dst shift));
|
match(Set dst (LShiftVI dst shift));
|
||||||
format %{ "pslld $dst,$shift\t! left shift packed2I" %}
|
format %{ "pslld $dst,$shift\t! left shift packed2I" %}
|
||||||
|
@ -3930,7 +3949,7 @@ instruct vsll2I_imm(vecD dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll2I_reg(vecD dst, vecD src, regF shift) %{
|
instruct vsll2I_reg(vecD dst, vecD src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
||||||
match(Set dst (LShiftVI src shift));
|
match(Set dst (LShiftVI src shift));
|
||||||
format %{ "vpslld $dst,$src,$shift\t! left shift packed2I" %}
|
format %{ "vpslld $dst,$src,$shift\t! left shift packed2I" %}
|
||||||
|
@ -3952,7 +3971,7 @@ instruct vsll2I_reg_imm(vecD dst, vecD src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll4I(vecX dst, regF shift) %{
|
instruct vsll4I(vecX dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 4);
|
predicate(n->as_Vector()->length() == 4);
|
||||||
match(Set dst (LShiftVI dst shift));
|
match(Set dst (LShiftVI dst shift));
|
||||||
format %{ "pslld $dst,$shift\t! left shift packed4I" %}
|
format %{ "pslld $dst,$shift\t! left shift packed4I" %}
|
||||||
|
@ -3972,7 +3991,7 @@ instruct vsll4I_imm(vecX dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll4I_reg(vecX dst, vecX src, regF shift) %{
|
instruct vsll4I_reg(vecX dst, vecX src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
|
||||||
match(Set dst (LShiftVI src shift));
|
match(Set dst (LShiftVI src shift));
|
||||||
format %{ "vpslld $dst,$src,$shift\t! left shift packed4I" %}
|
format %{ "vpslld $dst,$src,$shift\t! left shift packed4I" %}
|
||||||
|
@ -3994,7 +4013,7 @@ instruct vsll4I_reg_imm(vecX dst, vecX src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll8I_reg(vecY dst, vecY src, regF shift) %{
|
instruct vsll8I_reg(vecY dst, vecY src, vecS shift) %{
|
||||||
predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
|
predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
|
||||||
match(Set dst (LShiftVI src shift));
|
match(Set dst (LShiftVI src shift));
|
||||||
format %{ "vpslld $dst,$src,$shift\t! left shift packed8I" %}
|
format %{ "vpslld $dst,$src,$shift\t! left shift packed8I" %}
|
||||||
|
@ -4017,7 +4036,7 @@ instruct vsll8I_reg_imm(vecY dst, vecY src, immI8 shift) %{
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Longs vector left shift
|
// Longs vector left shift
|
||||||
instruct vsll2L(vecX dst, regF shift) %{
|
instruct vsll2L(vecX dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 2);
|
predicate(n->as_Vector()->length() == 2);
|
||||||
match(Set dst (LShiftVL dst shift));
|
match(Set dst (LShiftVL dst shift));
|
||||||
format %{ "psllq $dst,$shift\t! left shift packed2L" %}
|
format %{ "psllq $dst,$shift\t! left shift packed2L" %}
|
||||||
|
@ -4037,7 +4056,7 @@ instruct vsll2L_imm(vecX dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll2L_reg(vecX dst, vecX src, regF shift) %{
|
instruct vsll2L_reg(vecX dst, vecX src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
||||||
match(Set dst (LShiftVL src shift));
|
match(Set dst (LShiftVL src shift));
|
||||||
format %{ "vpsllq $dst,$src,$shift\t! left shift packed2L" %}
|
format %{ "vpsllq $dst,$src,$shift\t! left shift packed2L" %}
|
||||||
|
@ -4059,7 +4078,7 @@ instruct vsll2L_reg_imm(vecX dst, vecX src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsll4L_reg(vecY dst, vecY src, regF shift) %{
|
instruct vsll4L_reg(vecY dst, vecY src, vecS shift) %{
|
||||||
predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
|
predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
|
||||||
match(Set dst (LShiftVL src shift));
|
match(Set dst (LShiftVL src shift));
|
||||||
format %{ "vpsllq $dst,$src,$shift\t! left shift packed4L" %}
|
format %{ "vpsllq $dst,$src,$shift\t! left shift packed4L" %}
|
||||||
|
@ -4088,7 +4107,7 @@ instruct vsll4L_reg_imm(vecY dst, vecY src, immI8 shift) %{
|
||||||
// sign extension before a shift.
|
// sign extension before a shift.
|
||||||
|
|
||||||
// Integers vector logical right shift
|
// Integers vector logical right shift
|
||||||
instruct vsrl2I(vecD dst, regF shift) %{
|
instruct vsrl2I(vecD dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 2);
|
predicate(n->as_Vector()->length() == 2);
|
||||||
match(Set dst (URShiftVI dst shift));
|
match(Set dst (URShiftVI dst shift));
|
||||||
format %{ "psrld $dst,$shift\t! logical right shift packed2I" %}
|
format %{ "psrld $dst,$shift\t! logical right shift packed2I" %}
|
||||||
|
@ -4108,7 +4127,7 @@ instruct vsrl2I_imm(vecD dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsrl2I_reg(vecD dst, vecD src, regF shift) %{
|
instruct vsrl2I_reg(vecD dst, vecD src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
||||||
match(Set dst (URShiftVI src shift));
|
match(Set dst (URShiftVI src shift));
|
||||||
format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed2I" %}
|
format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed2I" %}
|
||||||
|
@ -4130,7 +4149,7 @@ instruct vsrl2I_reg_imm(vecD dst, vecD src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsrl4I(vecX dst, regF shift) %{
|
instruct vsrl4I(vecX dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 4);
|
predicate(n->as_Vector()->length() == 4);
|
||||||
match(Set dst (URShiftVI dst shift));
|
match(Set dst (URShiftVI dst shift));
|
||||||
format %{ "psrld $dst,$shift\t! logical right shift packed4I" %}
|
format %{ "psrld $dst,$shift\t! logical right shift packed4I" %}
|
||||||
|
@ -4150,7 +4169,7 @@ instruct vsrl4I_imm(vecX dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsrl4I_reg(vecX dst, vecX src, regF shift) %{
|
instruct vsrl4I_reg(vecX dst, vecX src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
|
||||||
match(Set dst (URShiftVI src shift));
|
match(Set dst (URShiftVI src shift));
|
||||||
format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed4I" %}
|
format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed4I" %}
|
||||||
|
@ -4172,7 +4191,7 @@ instruct vsrl4I_reg_imm(vecX dst, vecX src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsrl8I_reg(vecY dst, vecY src, regF shift) %{
|
instruct vsrl8I_reg(vecY dst, vecY src, vecS shift) %{
|
||||||
predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
|
predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
|
||||||
match(Set dst (URShiftVI src shift));
|
match(Set dst (URShiftVI src shift));
|
||||||
format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed8I" %}
|
format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed8I" %}
|
||||||
|
@ -4195,7 +4214,7 @@ instruct vsrl8I_reg_imm(vecY dst, vecY src, immI8 shift) %{
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Longs vector logical right shift
|
// Longs vector logical right shift
|
||||||
instruct vsrl2L(vecX dst, regF shift) %{
|
instruct vsrl2L(vecX dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 2);
|
predicate(n->as_Vector()->length() == 2);
|
||||||
match(Set dst (URShiftVL dst shift));
|
match(Set dst (URShiftVL dst shift));
|
||||||
format %{ "psrlq $dst,$shift\t! logical right shift packed2L" %}
|
format %{ "psrlq $dst,$shift\t! logical right shift packed2L" %}
|
||||||
|
@ -4215,7 +4234,7 @@ instruct vsrl2L_imm(vecX dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsrl2L_reg(vecX dst, vecX src, regF shift) %{
|
instruct vsrl2L_reg(vecX dst, vecX src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
||||||
match(Set dst (URShiftVL src shift));
|
match(Set dst (URShiftVL src shift));
|
||||||
format %{ "vpsrlq $dst,$src,$shift\t! logical right shift packed2L" %}
|
format %{ "vpsrlq $dst,$src,$shift\t! logical right shift packed2L" %}
|
||||||
|
@ -4237,7 +4256,7 @@ instruct vsrl2L_reg_imm(vecX dst, vecX src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsrl4L_reg(vecY dst, vecY src, regF shift) %{
|
instruct vsrl4L_reg(vecY dst, vecY src, vecS shift) %{
|
||||||
predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
|
predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
|
||||||
match(Set dst (URShiftVL src shift));
|
match(Set dst (URShiftVL src shift));
|
||||||
format %{ "vpsrlq $dst,$src,$shift\t! logical right shift packed4L" %}
|
format %{ "vpsrlq $dst,$src,$shift\t! logical right shift packed4L" %}
|
||||||
|
@ -4262,7 +4281,7 @@ instruct vsrl4L_reg_imm(vecY dst, vecY src, immI8 shift) %{
|
||||||
// ------------------- ArithmeticRightShift -----------------------------------
|
// ------------------- ArithmeticRightShift -----------------------------------
|
||||||
|
|
||||||
// Shorts/Chars vector arithmetic right shift
|
// Shorts/Chars vector arithmetic right shift
|
||||||
instruct vsra2S(vecS dst, regF shift) %{
|
instruct vsra2S(vecS dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 2);
|
predicate(n->as_Vector()->length() == 2);
|
||||||
match(Set dst (RShiftVS dst shift));
|
match(Set dst (RShiftVS dst shift));
|
||||||
format %{ "psraw $dst,$shift\t! arithmetic right shift packed2S" %}
|
format %{ "psraw $dst,$shift\t! arithmetic right shift packed2S" %}
|
||||||
|
@ -4282,7 +4301,7 @@ instruct vsra2S_imm(vecS dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsra2S_reg(vecS dst, vecS src, regF shift) %{
|
instruct vsra2S_reg(vecS dst, vecS src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
||||||
match(Set dst (RShiftVS src shift));
|
match(Set dst (RShiftVS src shift));
|
||||||
format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed2S" %}
|
format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed2S" %}
|
||||||
|
@ -4304,7 +4323,7 @@ instruct vsra2S_reg_imm(vecS dst, vecS src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsra4S(vecD dst, regF shift) %{
|
instruct vsra4S(vecD dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 4);
|
predicate(n->as_Vector()->length() == 4);
|
||||||
match(Set dst (RShiftVS dst shift));
|
match(Set dst (RShiftVS dst shift));
|
||||||
format %{ "psraw $dst,$shift\t! arithmetic right shift packed4S" %}
|
format %{ "psraw $dst,$shift\t! arithmetic right shift packed4S" %}
|
||||||
|
@ -4324,7 +4343,7 @@ instruct vsra4S_imm(vecD dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsra4S_reg(vecD dst, vecD src, regF shift) %{
|
instruct vsra4S_reg(vecD dst, vecD src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
|
||||||
match(Set dst (RShiftVS src shift));
|
match(Set dst (RShiftVS src shift));
|
||||||
format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed4S" %}
|
format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed4S" %}
|
||||||
|
@ -4346,7 +4365,7 @@ instruct vsra4S_reg_imm(vecD dst, vecD src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsra8S(vecX dst, regF shift) %{
|
instruct vsra8S(vecX dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 8);
|
predicate(n->as_Vector()->length() == 8);
|
||||||
match(Set dst (RShiftVS dst shift));
|
match(Set dst (RShiftVS dst shift));
|
||||||
format %{ "psraw $dst,$shift\t! arithmetic right shift packed8S" %}
|
format %{ "psraw $dst,$shift\t! arithmetic right shift packed8S" %}
|
||||||
|
@ -4366,7 +4385,7 @@ instruct vsra8S_imm(vecX dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsra8S_reg(vecX dst, vecX src, regF shift) %{
|
instruct vsra8S_reg(vecX dst, vecX src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
|
||||||
match(Set dst (RShiftVS src shift));
|
match(Set dst (RShiftVS src shift));
|
||||||
format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed8S" %}
|
format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed8S" %}
|
||||||
|
@ -4388,7 +4407,7 @@ instruct vsra8S_reg_imm(vecX dst, vecX src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsra16S_reg(vecY dst, vecY src, regF shift) %{
|
instruct vsra16S_reg(vecY dst, vecY src, vecS shift) %{
|
||||||
predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
|
predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
|
||||||
match(Set dst (RShiftVS src shift));
|
match(Set dst (RShiftVS src shift));
|
||||||
format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed16S" %}
|
format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed16S" %}
|
||||||
|
@ -4411,7 +4430,7 @@ instruct vsra16S_reg_imm(vecY dst, vecY src, immI8 shift) %{
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Integers vector arithmetic right shift
|
// Integers vector arithmetic right shift
|
||||||
instruct vsra2I(vecD dst, regF shift) %{
|
instruct vsra2I(vecD dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 2);
|
predicate(n->as_Vector()->length() == 2);
|
||||||
match(Set dst (RShiftVI dst shift));
|
match(Set dst (RShiftVI dst shift));
|
||||||
format %{ "psrad $dst,$shift\t! arithmetic right shift packed2I" %}
|
format %{ "psrad $dst,$shift\t! arithmetic right shift packed2I" %}
|
||||||
|
@ -4431,7 +4450,7 @@ instruct vsra2I_imm(vecD dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsra2I_reg(vecD dst, vecD src, regF shift) %{
|
instruct vsra2I_reg(vecD dst, vecD src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
|
||||||
match(Set dst (RShiftVI src shift));
|
match(Set dst (RShiftVI src shift));
|
||||||
format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed2I" %}
|
format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed2I" %}
|
||||||
|
@ -4453,7 +4472,7 @@ instruct vsra2I_reg_imm(vecD dst, vecD src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsra4I(vecX dst, regF shift) %{
|
instruct vsra4I(vecX dst, vecS shift) %{
|
||||||
predicate(n->as_Vector()->length() == 4);
|
predicate(n->as_Vector()->length() == 4);
|
||||||
match(Set dst (RShiftVI dst shift));
|
match(Set dst (RShiftVI dst shift));
|
||||||
format %{ "psrad $dst,$shift\t! arithmetic right shift packed4I" %}
|
format %{ "psrad $dst,$shift\t! arithmetic right shift packed4I" %}
|
||||||
|
@ -4473,7 +4492,7 @@ instruct vsra4I_imm(vecX dst, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsra4I_reg(vecX dst, vecX src, regF shift) %{
|
instruct vsra4I_reg(vecX dst, vecX src, vecS shift) %{
|
||||||
predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
|
predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
|
||||||
match(Set dst (RShiftVI src shift));
|
match(Set dst (RShiftVI src shift));
|
||||||
format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed4I" %}
|
format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed4I" %}
|
||||||
|
@ -4495,7 +4514,7 @@ instruct vsra4I_reg_imm(vecX dst, vecX src, immI8 shift) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vsra8I_reg(vecY dst, vecY src, regF shift) %{
|
instruct vsra8I_reg(vecY dst, vecY src, vecS shift) %{
|
||||||
predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
|
predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
|
||||||
match(Set dst (RShiftVI src shift));
|
match(Set dst (RShiftVI src shift));
|
||||||
format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed8I" %}
|
format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed8I" %}
|
||||||
|
|
|
@ -82,12 +82,6 @@
|
||||||
# include "assembler_ppc.inline.hpp"
|
# include "assembler_ppc.inline.hpp"
|
||||||
# include "nativeInst_ppc.hpp"
|
# include "nativeInst_ppc.hpp"
|
||||||
#endif
|
#endif
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// put OS-includes here
|
// put OS-includes here
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
|
|
|
@ -82,12 +82,6 @@
|
||||||
# include "assembler_ppc.inline.hpp"
|
# include "assembler_ppc.inline.hpp"
|
||||||
# include "nativeInst_ppc.hpp"
|
# include "nativeInst_ppc.hpp"
|
||||||
#endif
|
#endif
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// put OS-includes here
|
// put OS-includes here
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
|
|
|
@ -70,12 +70,6 @@
|
||||||
# include "assembler_sparc.inline.hpp"
|
# include "assembler_sparc.inline.hpp"
|
||||||
# include "nativeInst_sparc.hpp"
|
# include "nativeInst_sparc.hpp"
|
||||||
#endif
|
#endif
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// put OS-includes here
|
// put OS-includes here
|
||||||
# include <dlfcn.h>
|
# include <dlfcn.h>
|
||||||
|
|
|
@ -69,12 +69,6 @@
|
||||||
# include "assembler_x86.inline.hpp"
|
# include "assembler_x86.inline.hpp"
|
||||||
# include "nativeInst_x86.hpp"
|
# include "nativeInst_x86.hpp"
|
||||||
#endif
|
#endif
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
|
|
|
@ -52,12 +52,6 @@
|
||||||
#include "thread_bsd.inline.hpp"
|
#include "thread_bsd.inline.hpp"
|
||||||
#include "utilities/events.hpp"
|
#include "utilities/events.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// put OS-includes here
|
// put OS-includes here
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
|
|
|
@ -58,12 +58,6 @@
|
||||||
#include "thread_bsd.inline.hpp"
|
#include "thread_bsd.inline.hpp"
|
||||||
#include "utilities/events.hpp"
|
#include "utilities/events.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
address os::current_stack_pointer() {
|
address os::current_stack_pointer() {
|
||||||
address dummy = (address) &dummy;
|
address dummy = (address) &dummy;
|
||||||
|
|
|
@ -52,13 +52,6 @@
|
||||||
#include "thread_linux.inline.hpp"
|
#include "thread_linux.inline.hpp"
|
||||||
#include "utilities/events.hpp"
|
#include "utilities/events.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Linux/Sparc has rather obscure naming of registers in sigcontext
|
// Linux/Sparc has rather obscure naming of registers in sigcontext
|
||||||
// different between 32 and 64 bits
|
// different between 32 and 64 bits
|
||||||
|
|
|
@ -52,12 +52,6 @@
|
||||||
#include "thread_linux.inline.hpp"
|
#include "thread_linux.inline.hpp"
|
||||||
#include "utilities/events.hpp"
|
#include "utilities/events.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// put OS-includes here
|
// put OS-includes here
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
|
|
|
@ -53,12 +53,6 @@
|
||||||
#include "thread_linux.inline.hpp"
|
#include "thread_linux.inline.hpp"
|
||||||
#include "utilities/events.hpp"
|
#include "utilities/events.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
address os::current_stack_pointer() {
|
address os::current_stack_pointer() {
|
||||||
address dummy = (address) &dummy;
|
address dummy = (address) &dummy;
|
||||||
|
|
|
@ -52,13 +52,6 @@
|
||||||
#include "thread_solaris.inline.hpp"
|
#include "thread_solaris.inline.hpp"
|
||||||
#include "utilities/events.hpp"
|
#include "utilities/events.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
# include <signal.h> // needed first to avoid name collision for "std" with SC 5.0
|
# include <signal.h> // needed first to avoid name collision for "std" with SC 5.0
|
||||||
|
|
||||||
|
|
|
@ -52,12 +52,6 @@
|
||||||
#include "thread_solaris.inline.hpp"
|
#include "thread_solaris.inline.hpp"
|
||||||
#include "utilities/events.hpp"
|
#include "utilities/events.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// put OS-includes here
|
// put OS-includes here
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
|
|
|
@ -52,12 +52,6 @@
|
||||||
#include "thread_windows.inline.hpp"
|
#include "thread_windows.inline.hpp"
|
||||||
#include "utilities/events.hpp"
|
#include "utilities/events.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#ifdef COMPILER1
|
|
||||||
#include "c1/c1_Runtime1.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER2
|
|
||||||
#include "opto/runtime.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "unwind_windows_x86.hpp"
|
# include "unwind_windows_x86.hpp"
|
||||||
#undef REG_SP
|
#undef REG_SP
|
||||||
|
|
|
@ -4049,6 +4049,7 @@ bool MatchRule::is_vector() const {
|
||||||
"MulVS","MulVI","MulVF","MulVD",
|
"MulVS","MulVI","MulVF","MulVD",
|
||||||
"DivVF","DivVD",
|
"DivVF","DivVD",
|
||||||
"AndV" ,"XorV" ,"OrV",
|
"AndV" ,"XorV" ,"OrV",
|
||||||
|
"LShiftCntV","RShiftCntV",
|
||||||
"LShiftVB","LShiftVS","LShiftVI","LShiftVL",
|
"LShiftVB","LShiftVS","LShiftVI","LShiftVL",
|
||||||
"RShiftVB","RShiftVS","RShiftVI","RShiftVL",
|
"RShiftVB","RShiftVS","RShiftVI","RShiftVL",
|
||||||
"URShiftVB","URShiftVS","URShiftVI","URShiftVL",
|
"URShiftVB","URShiftVS","URShiftVI","URShiftVL",
|
||||||
|
|
|
@ -49,6 +49,7 @@ class ciInstance;
|
||||||
class ciCallSite;
|
class ciCallSite;
|
||||||
class ciMemberName;
|
class ciMemberName;
|
||||||
class ciMethodHandle;
|
class ciMethodHandle;
|
||||||
|
class ciMethodType;
|
||||||
class ciArray;
|
class ciArray;
|
||||||
class ciObjArray;
|
class ciObjArray;
|
||||||
class ciTypeArray;
|
class ciTypeArray;
|
||||||
|
@ -99,6 +100,7 @@ friend class ciMemberName; \
|
||||||
friend class ciMethod; \
|
friend class ciMethod; \
|
||||||
friend class ciMethodData; \
|
friend class ciMethodData; \
|
||||||
friend class ciMethodHandle; \
|
friend class ciMethodHandle; \
|
||||||
|
friend class ciMethodType; \
|
||||||
friend class ciReceiverTypeData; \
|
friend class ciReceiverTypeData; \
|
||||||
friend class ciSymbol; \
|
friend class ciSymbol; \
|
||||||
friend class ciArray; \
|
friend class ciArray; \
|
||||||
|
|
76
hotspot/src/share/vm/ci/ciMethodType.hpp
Normal file
76
hotspot/src/share/vm/ci/ciMethodType.hpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHARE_VM_CI_CIMETHODTYPE_HPP
|
||||||
|
#define SHARE_VM_CI_CIMETHODTYPE_HPP
|
||||||
|
|
||||||
|
#include "ci/ciInstance.hpp"
|
||||||
|
#include "ci/ciUtilities.hpp"
|
||||||
|
#include "classfile/javaClasses.hpp"
|
||||||
|
|
||||||
|
// ciMethodType
|
||||||
|
//
|
||||||
|
// The class represents a java.lang.invoke.MethodType object.
|
||||||
|
class ciMethodType : public ciInstance {
|
||||||
|
private:
|
||||||
|
ciType* class_to_citype(oop klass_oop) const {
|
||||||
|
if (java_lang_Class::is_primitive(klass_oop)) {
|
||||||
|
BasicType bt = java_lang_Class::primitive_type(klass_oop);
|
||||||
|
return ciType::make(bt);
|
||||||
|
} else {
|
||||||
|
Klass* k = java_lang_Class::as_Klass(klass_oop);
|
||||||
|
return CURRENT_ENV->get_klass(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ciMethodType(instanceHandle h_i) : ciInstance(h_i) {}
|
||||||
|
|
||||||
|
// What kind of ciObject is this?
|
||||||
|
bool is_method_type() const { return true; }
|
||||||
|
|
||||||
|
ciType* rtype() const {
|
||||||
|
GUARDED_VM_ENTRY(
|
||||||
|
oop rtype = java_lang_invoke_MethodType::rtype(get_oop());
|
||||||
|
return class_to_citype(rtype);
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
int ptype_count() const {
|
||||||
|
GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_count(get_oop());)
|
||||||
|
}
|
||||||
|
|
||||||
|
int ptype_slot_count() const {
|
||||||
|
GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_slot_count(get_oop());)
|
||||||
|
}
|
||||||
|
|
||||||
|
ciType* ptype_at(int index) const {
|
||||||
|
GUARDED_VM_ENTRY(
|
||||||
|
oop ptype = java_lang_invoke_MethodType::ptype(get_oop(), index);
|
||||||
|
return class_to_citype(ptype);
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SHARE_VM_CI_CIMETHODTYPE_HPP
|
|
@ -123,6 +123,7 @@ public:
|
||||||
virtual bool is_instance() { return false; }
|
virtual bool is_instance() { return false; }
|
||||||
virtual bool is_member_name() const { return false; }
|
virtual bool is_member_name() const { return false; }
|
||||||
virtual bool is_method_handle() const { return false; }
|
virtual bool is_method_handle() const { return false; }
|
||||||
|
virtual bool is_method_type() const { return false; }
|
||||||
virtual bool is_array() { return false; }
|
virtual bool is_array() { return false; }
|
||||||
virtual bool is_obj_array() { return false; }
|
virtual bool is_obj_array() { return false; }
|
||||||
virtual bool is_type_array() { return false; }
|
virtual bool is_type_array() { return false; }
|
||||||
|
@ -142,35 +143,39 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subclass casting with assertions.
|
// Subclass casting with assertions.
|
||||||
ciNullObject* as_null_object() {
|
ciNullObject* as_null_object() {
|
||||||
assert(is_null_object(), "bad cast");
|
assert(is_null_object(), "bad cast");
|
||||||
return (ciNullObject*)this;
|
return (ciNullObject*)this;
|
||||||
}
|
}
|
||||||
ciCallSite* as_call_site() {
|
ciCallSite* as_call_site() {
|
||||||
assert(is_call_site(), "bad cast");
|
assert(is_call_site(), "bad cast");
|
||||||
return (ciCallSite*) this;
|
return (ciCallSite*)this;
|
||||||
}
|
}
|
||||||
ciInstance* as_instance() {
|
ciInstance* as_instance() {
|
||||||
assert(is_instance(), "bad cast");
|
assert(is_instance(), "bad cast");
|
||||||
return (ciInstance*)this;
|
return (ciInstance*)this;
|
||||||
}
|
}
|
||||||
ciMemberName* as_member_name() {
|
ciMemberName* as_member_name() {
|
||||||
assert(is_member_name(), "bad cast");
|
assert(is_member_name(), "bad cast");
|
||||||
return (ciMemberName*)this;
|
return (ciMemberName*)this;
|
||||||
}
|
}
|
||||||
ciMethodHandle* as_method_handle() {
|
ciMethodHandle* as_method_handle() {
|
||||||
assert(is_method_handle(), "bad cast");
|
assert(is_method_handle(), "bad cast");
|
||||||
return (ciMethodHandle*) this;
|
return (ciMethodHandle*)this;
|
||||||
}
|
}
|
||||||
ciArray* as_array() {
|
ciMethodType* as_method_type() {
|
||||||
|
assert(is_method_type(), "bad cast");
|
||||||
|
return (ciMethodType*)this;
|
||||||
|
}
|
||||||
|
ciArray* as_array() {
|
||||||
assert(is_array(), "bad cast");
|
assert(is_array(), "bad cast");
|
||||||
return (ciArray*)this;
|
return (ciArray*)this;
|
||||||
}
|
}
|
||||||
ciObjArray* as_obj_array() {
|
ciObjArray* as_obj_array() {
|
||||||
assert(is_obj_array(), "bad cast");
|
assert(is_obj_array(), "bad cast");
|
||||||
return (ciObjArray*)this;
|
return (ciObjArray*)this;
|
||||||
}
|
}
|
||||||
ciTypeArray* as_type_array() {
|
ciTypeArray* as_type_array() {
|
||||||
assert(is_type_array(), "bad cast");
|
assert(is_type_array(), "bad cast");
|
||||||
return (ciTypeArray*)this;
|
return (ciTypeArray*)this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "ci/ciMethod.hpp"
|
#include "ci/ciMethod.hpp"
|
||||||
#include "ci/ciMethodData.hpp"
|
#include "ci/ciMethodData.hpp"
|
||||||
#include "ci/ciMethodHandle.hpp"
|
#include "ci/ciMethodHandle.hpp"
|
||||||
|
#include "ci/ciMethodType.hpp"
|
||||||
#include "ci/ciNullObject.hpp"
|
#include "ci/ciNullObject.hpp"
|
||||||
#include "ci/ciObjArray.hpp"
|
#include "ci/ciObjArray.hpp"
|
||||||
#include "ci/ciObjArrayKlass.hpp"
|
#include "ci/ciObjArrayKlass.hpp"
|
||||||
|
@ -237,23 +238,23 @@ ciObject* ciObjectFactory::get(oop key) {
|
||||||
|
|
||||||
assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be");
|
assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be");
|
||||||
|
|
||||||
NonPermObject* &bucket = find_non_perm(key);
|
NonPermObject* &bucket = find_non_perm(key);
|
||||||
if (bucket != NULL) {
|
if (bucket != NULL) {
|
||||||
return bucket->object();
|
return bucket->object();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The ciObject does not yet exist. Create it and insert it
|
// The ciObject does not yet exist. Create it and insert it
|
||||||
// into the cache.
|
// into the cache.
|
||||||
Handle keyHandle(key);
|
Handle keyHandle(key);
|
||||||
ciObject* new_object = create_new_object(keyHandle());
|
ciObject* new_object = create_new_object(keyHandle());
|
||||||
assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
|
assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
|
||||||
init_ident_of(new_object);
|
init_ident_of(new_object);
|
||||||
assert(Universe::heap()->is_in_reserved(new_object->get_oop()), "must be");
|
assert(Universe::heap()->is_in_reserved(new_object->get_oop()), "must be");
|
||||||
|
|
||||||
// Not a perm-space object.
|
// Not a perm-space object.
|
||||||
insert_non_perm(bucket, keyHandle(), new_object);
|
insert_non_perm(bucket, keyHandle(), new_object);
|
||||||
return new_object;
|
return new_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciObjectFactory::get
|
// ciObjectFactory::get
|
||||||
|
@ -324,6 +325,8 @@ ciObject* ciObjectFactory::create_new_object(oop o) {
|
||||||
return new (arena()) ciMemberName(h_i);
|
return new (arena()) ciMemberName(h_i);
|
||||||
else if (java_lang_invoke_MethodHandle::is_instance(o))
|
else if (java_lang_invoke_MethodHandle::is_instance(o))
|
||||||
return new (arena()) ciMethodHandle(h_i);
|
return new (arena()) ciMethodHandle(h_i);
|
||||||
|
else if (java_lang_invoke_MethodType::is_instance(o))
|
||||||
|
return new (arena()) ciMethodType(h_i);
|
||||||
else
|
else
|
||||||
return new (arena()) ciInstance(h_i);
|
return new (arena()) ciInstance(h_i);
|
||||||
} else if (o->is_objArray()) {
|
} else if (o->is_objArray()) {
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
|
#include "ci/ciMethodType.hpp"
|
||||||
#include "ci/ciSignature.hpp"
|
#include "ci/ciSignature.hpp"
|
||||||
#include "ci/ciUtilities.hpp"
|
#include "ci/ciUtilities.hpp"
|
||||||
#include "memory/allocation.inline.hpp"
|
#include "memory/allocation.inline.hpp"
|
||||||
|
@ -79,6 +80,24 @@ ciSignature::ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciS
|
||||||
_count = count;
|
_count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// ciSignature::ciSignature
|
||||||
|
ciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol, ciMethodType* method_type) :
|
||||||
|
_symbol(symbol),
|
||||||
|
_accessing_klass(accessing_klass),
|
||||||
|
_size( method_type->ptype_slot_count()),
|
||||||
|
_count(method_type->ptype_count())
|
||||||
|
{
|
||||||
|
ASSERT_IN_VM;
|
||||||
|
EXCEPTION_CONTEXT;
|
||||||
|
Arena* arena = CURRENT_ENV->arena();
|
||||||
|
_types = new (arena) GrowableArray<ciType*>(arena, _count + 1, 0, NULL);
|
||||||
|
for (int i = 0; i < _count; i++) {
|
||||||
|
_types->append(method_type->ptype_at(i));
|
||||||
|
}
|
||||||
|
_types->append(method_type->rtype());
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciSignature::return_type
|
// ciSignature::return_type
|
||||||
//
|
//
|
||||||
|
|
|
@ -47,6 +47,7 @@ private:
|
||||||
friend class ciObjectFactory;
|
friend class ciObjectFactory;
|
||||||
|
|
||||||
ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* signature);
|
ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* signature);
|
||||||
|
ciSignature(ciKlass* accessing_klass, ciSymbol* signature, ciMethodType* method_type);
|
||||||
|
|
||||||
void get_all_klasses();
|
void get_all_klasses();
|
||||||
|
|
||||||
|
|
|
@ -364,12 +364,15 @@ ciMethod* ciBytecodeStream::get_method(bool& will_link, ciSignature* *declared_s
|
||||||
constantPoolHandle cpool(_method->get_Method()->constants());
|
constantPoolHandle cpool(_method->get_Method()->constants());
|
||||||
ciMethod* m = env->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
|
ciMethod* m = env->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
|
||||||
will_link = m->is_loaded();
|
will_link = m->is_loaded();
|
||||||
// Get declared method signature and return it.
|
|
||||||
if (has_optional_appendix()) {
|
// Use the MethodType stored in the CP cache to create a signature
|
||||||
const int sig_index = get_method_signature_index();
|
// with correct types (in respect to class loaders).
|
||||||
Symbol* sig_sym = cpool->symbol_at(sig_index);
|
if (has_method_type()) {
|
||||||
ciKlass* pool_holder = env->get_klass(cpool->pool_holder());
|
ciSymbol* sig_sym = env->get_symbol(cpool->symbol_at(get_method_signature_index()));
|
||||||
(*declared_signature_result) = new (env->arena()) ciSignature(pool_holder, cpool, env->get_symbol(sig_sym));
|
ciKlass* pool_holder = env->get_klass(cpool->pool_holder());
|
||||||
|
ciMethodType* method_type = get_method_type();
|
||||||
|
ciSignature* declared_signature = new (env->arena()) ciSignature(pool_holder, sig_sym, method_type);
|
||||||
|
(*declared_signature_result) = declared_signature;
|
||||||
} else {
|
} else {
|
||||||
(*declared_signature_result) = m->signature();
|
(*declared_signature_result) = m->signature();
|
||||||
}
|
}
|
||||||
|
@ -399,6 +402,31 @@ ciObject* ciBytecodeStream::get_appendix() {
|
||||||
return CURRENT_ENV->get_object(appendix_oop);
|
return CURRENT_ENV->get_object(appendix_oop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// ciBytecodeStream::has_method_type
|
||||||
|
//
|
||||||
|
// Returns true if there is a MethodType argument stored in the
|
||||||
|
// constant pool cache at the current bci.
|
||||||
|
bool ciBytecodeStream::has_method_type() {
|
||||||
|
GUARDED_VM_ENTRY(
|
||||||
|
constantPoolHandle cpool(_method->get_Method()->constants());
|
||||||
|
return ConstantPool::has_method_type_at_if_loaded(cpool, get_method_index());
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// ciBytecodeStream::get_method_type
|
||||||
|
//
|
||||||
|
// Return the MethodType stored in the constant pool cache at
|
||||||
|
// the current bci.
|
||||||
|
ciMethodType* ciBytecodeStream::get_method_type() {
|
||||||
|
GUARDED_VM_ENTRY(
|
||||||
|
constantPoolHandle cpool(_method->get_Method()->constants());
|
||||||
|
oop method_type_oop = ConstantPool::method_type_at_if_loaded(cpool, get_method_index());
|
||||||
|
return CURRENT_ENV->get_object(method_type_oop)->as_method_type();
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciBytecodeStream::get_declared_method_holder
|
// ciBytecodeStream::get_declared_method_holder
|
||||||
//
|
//
|
||||||
|
|
|
@ -257,12 +257,14 @@ public:
|
||||||
int get_field_holder_index();
|
int get_field_holder_index();
|
||||||
int get_field_signature_index();
|
int get_field_signature_index();
|
||||||
|
|
||||||
ciMethod* get_method(bool& will_link, ciSignature* *declared_signature_result);
|
ciMethod* get_method(bool& will_link, ciSignature* *declared_signature_result);
|
||||||
bool has_appendix();
|
bool has_appendix();
|
||||||
ciObject* get_appendix();
|
ciObject* get_appendix();
|
||||||
ciKlass* get_declared_method_holder();
|
bool has_method_type();
|
||||||
int get_method_holder_index();
|
ciMethodType* get_method_type();
|
||||||
int get_method_signature_index();
|
ciKlass* get_declared_method_holder();
|
||||||
|
int get_method_holder_index();
|
||||||
|
int get_method_signature_index();
|
||||||
|
|
||||||
// Get the resolved references arrays from the constant pool
|
// Get the resolved references arrays from the constant pool
|
||||||
ciObjArray* get_resolved_references();
|
ciObjArray* get_resolved_references();
|
||||||
|
|
|
@ -2194,6 +2194,10 @@ bool ciTypeFlow::clone_loop_heads(Loop* lp, StateVector* temp_vector, JsrSet* te
|
||||||
if (head->backedge_copy_count() != 0)
|
if (head->backedge_copy_count() != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Don't clone head of OSR loop to get correct types in start block.
|
||||||
|
if (is_osr_flow() && head->start() == start_bci())
|
||||||
|
continue;
|
||||||
|
|
||||||
// check _no_ shared head below us
|
// check _no_ shared head below us
|
||||||
Loop* ch;
|
Loop* ch;
|
||||||
for (ch = lp->child(); ch != NULL && ch->head() != head; ch = ch->sibling());
|
for (ch = lp->child(); ch != NULL && ch->head() != head; ch = ch->sibling());
|
||||||
|
|
|
@ -2429,7 +2429,8 @@ static methodHandle unpack_method_and_appendix(Handle mname,
|
||||||
methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name,
|
methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name,
|
||||||
Symbol* signature,
|
Symbol* signature,
|
||||||
KlassHandle accessing_klass,
|
KlassHandle accessing_klass,
|
||||||
Handle* appendix_result,
|
Handle *appendix_result,
|
||||||
|
Handle *method_type_result,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
methodHandle empty;
|
methodHandle empty;
|
||||||
assert(EnableInvokeDynamic, "");
|
assert(EnableInvokeDynamic, "");
|
||||||
|
@ -2461,6 +2462,7 @@ methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name,
|
||||||
vmSymbols::linkMethod_signature(),
|
vmSymbols::linkMethod_signature(),
|
||||||
&args, CHECK_(empty));
|
&args, CHECK_(empty));
|
||||||
Handle mname(THREAD, (oop) result.get_jobject());
|
Handle mname(THREAD, (oop) result.get_jobject());
|
||||||
|
(*method_type_result) = method_type;
|
||||||
return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD);
|
return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2607,7 +2609,8 @@ methodHandle SystemDictionary::find_dynamic_call_site_invoker(KlassHandle caller
|
||||||
Handle bootstrap_specifier,
|
Handle bootstrap_specifier,
|
||||||
Symbol* name,
|
Symbol* name,
|
||||||
Symbol* type,
|
Symbol* type,
|
||||||
Handle* appendix_result,
|
Handle *appendix_result,
|
||||||
|
Handle *method_type_result,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
methodHandle empty;
|
methodHandle empty;
|
||||||
Handle bsm, info;
|
Handle bsm, info;
|
||||||
|
@ -2650,6 +2653,7 @@ methodHandle SystemDictionary::find_dynamic_call_site_invoker(KlassHandle caller
|
||||||
vmSymbols::linkCallSite_signature(),
|
vmSymbols::linkCallSite_signature(),
|
||||||
&args, CHECK_(empty));
|
&args, CHECK_(empty));
|
||||||
Handle mname(THREAD, (oop) result.get_jobject());
|
Handle mname(THREAD, (oop) result.get_jobject());
|
||||||
|
(*method_type_result) = method_type;
|
||||||
return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD);
|
return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -497,6 +497,7 @@ public:
|
||||||
Symbol* signature,
|
Symbol* signature,
|
||||||
KlassHandle accessing_klass,
|
KlassHandle accessing_klass,
|
||||||
Handle *appendix_result,
|
Handle *appendix_result,
|
||||||
|
Handle *method_type_result,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
// for a given signature, find the internal MethodHandle method (linkTo* or invokeBasic)
|
// for a given signature, find the internal MethodHandle method (linkTo* or invokeBasic)
|
||||||
// (does not ask Java, since this is a low-level intrinsic defined by the JVM)
|
// (does not ask Java, since this is a low-level intrinsic defined by the JVM)
|
||||||
|
@ -523,6 +524,7 @@ public:
|
||||||
Symbol* name,
|
Symbol* name,
|
||||||
Symbol* type,
|
Symbol* type,
|
||||||
Handle *appendix_result,
|
Handle *appendix_result,
|
||||||
|
Handle *method_type_result,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
|
|
||||||
// Utility for printing loader "name" as part of tracing constraints
|
// Utility for printing loader "name" as part of tracing constraints
|
||||||
|
|
|
@ -1195,9 +1195,9 @@ void CMSAdaptiveSizePolicy::compute_tenured_generation_free_space(
|
||||||
set_promo_size(desired_promo_size);
|
set_promo_size(desired_promo_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CMSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
|
uint CMSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
|
||||||
bool is_survivor_overflow,
|
bool is_survivor_overflow,
|
||||||
int tenuring_threshold,
|
uint tenuring_threshold,
|
||||||
size_t survivor_limit) {
|
size_t survivor_limit) {
|
||||||
assert(survivor_limit >= generation_alignment(),
|
assert(survivor_limit >= generation_alignment(),
|
||||||
"survivor_limit too small");
|
"survivor_limit too small");
|
||||||
|
@ -1315,7 +1315,7 @@ int CMSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
|
||||||
|
|
||||||
gclog_or_tty->print( " avg_promoted_padded_avg: %f"
|
gclog_or_tty->print( " avg_promoted_padded_avg: %f"
|
||||||
" avg_pretenured_padded_avg: %f"
|
" avg_pretenured_padded_avg: %f"
|
||||||
" tenuring_thresh: %d"
|
" tenuring_thresh: %u"
|
||||||
" target_size: " SIZE_FORMAT
|
" target_size: " SIZE_FORMAT
|
||||||
" survivor_limit: " SIZE_FORMAT,
|
" survivor_limit: " SIZE_FORMAT,
|
||||||
gch->gc_stats(1)->avg_promoted()->padded_average(),
|
gch->gc_stats(1)->avg_promoted()->padded_average(),
|
||||||
|
|
|
@ -440,9 +440,9 @@ class CMSAdaptiveSizePolicy : public AdaptiveSizePolicy {
|
||||||
size_t max_eden_size);
|
size_t max_eden_size);
|
||||||
// Calculates new survivor space size; returns a new tenuring threshold
|
// Calculates new survivor space size; returns a new tenuring threshold
|
||||||
// value. Stores new survivor size in _survivor_size.
|
// value. Stores new survivor size in _survivor_size.
|
||||||
virtual int compute_survivor_space_size_and_threshold(
|
virtual uint compute_survivor_space_size_and_threshold(
|
||||||
bool is_survivor_overflow,
|
bool is_survivor_overflow,
|
||||||
int tenuring_threshold,
|
uint tenuring_threshold,
|
||||||
size_t survivor_limit);
|
size_t survivor_limit);
|
||||||
|
|
||||||
virtual void compute_tenured_generation_free_space(size_t cur_tenured_free,
|
virtual void compute_tenured_generation_free_space(size_t cur_tenured_free,
|
||||||
|
|
|
@ -1188,29 +1188,14 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
|
||||||
// liveness counting data.
|
// liveness counting data.
|
||||||
class CMCountDataClosureBase: public HeapRegionClosure {
|
class CMCountDataClosureBase: public HeapRegionClosure {
|
||||||
protected:
|
protected:
|
||||||
|
G1CollectedHeap* _g1h;
|
||||||
ConcurrentMark* _cm;
|
ConcurrentMark* _cm;
|
||||||
|
CardTableModRefBS* _ct_bs;
|
||||||
|
|
||||||
BitMap* _region_bm;
|
BitMap* _region_bm;
|
||||||
BitMap* _card_bm;
|
BitMap* _card_bm;
|
||||||
|
|
||||||
void set_card_bitmap_range(BitMap::idx_t start_idx, BitMap::idx_t last_idx) {
|
// Takes a region that's not empty (i.e., it has at least one
|
||||||
assert(start_idx <= last_idx, "sanity");
|
|
||||||
|
|
||||||
// Set the inclusive bit range [start_idx, last_idx].
|
|
||||||
// For small ranges (up to 8 cards) use a simple loop; otherwise
|
|
||||||
// use par_at_put_range.
|
|
||||||
if ((last_idx - start_idx) < 8) {
|
|
||||||
for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
|
|
||||||
_card_bm->par_set_bit(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assert(last_idx < _card_bm->size(), "sanity");
|
|
||||||
// Note BitMap::par_at_put_range() is exclusive.
|
|
||||||
BitMap::idx_t max_idx = MAX2(last_idx+1, _card_bm->size());
|
|
||||||
_card_bm->par_at_put_range(start_idx, max_idx, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// It takes a region that's not empty (i.e., it has at least one
|
|
||||||
// live object in it and sets its corresponding bit on the region
|
// live object in it and sets its corresponding bit on the region
|
||||||
// bitmap to 1. If the region is "starts humongous" it will also set
|
// bitmap to 1. If the region is "starts humongous" it will also set
|
||||||
// to 1 the bits on the region bitmap that correspond to its
|
// to 1 the bits on the region bitmap that correspond to its
|
||||||
|
@ -1231,9 +1216,11 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMCountDataClosureBase(ConcurrentMark *cm,
|
CMCountDataClosureBase(G1CollectedHeap* g1h,
|
||||||
BitMap* region_bm, BitMap* card_bm):
|
BitMap* region_bm, BitMap* card_bm):
|
||||||
_cm(cm), _region_bm(region_bm), _card_bm(card_bm) { }
|
_g1h(g1h), _cm(g1h->concurrent_mark()),
|
||||||
|
_ct_bs((CardTableModRefBS*) (g1h->barrier_set())),
|
||||||
|
_region_bm(region_bm), _card_bm(card_bm) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Closure that calculates the # live objects per region. Used
|
// Closure that calculates the # live objects per region. Used
|
||||||
|
@ -1243,9 +1230,9 @@ class CalcLiveObjectsClosure: public CMCountDataClosureBase {
|
||||||
size_t _region_marked_bytes;
|
size_t _region_marked_bytes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CalcLiveObjectsClosure(CMBitMapRO *bm, ConcurrentMark *cm,
|
CalcLiveObjectsClosure(CMBitMapRO *bm, G1CollectedHeap* g1h,
|
||||||
BitMap* region_bm, BitMap* card_bm) :
|
BitMap* region_bm, BitMap* card_bm) :
|
||||||
CMCountDataClosureBase(cm, region_bm, card_bm),
|
CMCountDataClosureBase(g1h, region_bm, card_bm),
|
||||||
_bm(bm), _region_marked_bytes(0) { }
|
_bm(bm), _region_marked_bytes(0) { }
|
||||||
|
|
||||||
bool doHeapRegion(HeapRegion* hr) {
|
bool doHeapRegion(HeapRegion* hr) {
|
||||||
|
@ -1261,44 +1248,63 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapWord* nextTop = hr->next_top_at_mark_start();
|
HeapWord* ntams = hr->next_top_at_mark_start();
|
||||||
HeapWord* start = hr->bottom();
|
HeapWord* start = hr->bottom();
|
||||||
|
|
||||||
assert(start <= hr->end() && start <= nextTop && nextTop <= hr->end(),
|
assert(start <= hr->end() && start <= ntams && ntams <= hr->end(),
|
||||||
err_msg("Preconditions not met - "
|
err_msg("Preconditions not met - "
|
||||||
"start: "PTR_FORMAT", nextTop: "PTR_FORMAT", end: "PTR_FORMAT,
|
"start: "PTR_FORMAT", ntams: "PTR_FORMAT", end: "PTR_FORMAT,
|
||||||
start, nextTop, hr->end()));
|
start, ntams, hr->end()));
|
||||||
|
|
||||||
// Find the first marked object at or after "start".
|
// Find the first marked object at or after "start".
|
||||||
start = _bm->getNextMarkedWordAddress(start, nextTop);
|
start = _bm->getNextMarkedWordAddress(start, ntams);
|
||||||
|
|
||||||
size_t marked_bytes = 0;
|
size_t marked_bytes = 0;
|
||||||
|
|
||||||
while (start < nextTop) {
|
while (start < ntams) {
|
||||||
oop obj = oop(start);
|
oop obj = oop(start);
|
||||||
int obj_sz = obj->size();
|
int obj_sz = obj->size();
|
||||||
HeapWord* obj_last = start + obj_sz - 1;
|
HeapWord* obj_end = start + obj_sz;
|
||||||
|
|
||||||
BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
|
BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
|
||||||
BitMap::idx_t last_idx = _cm->card_bitmap_index_for(obj_last);
|
BitMap::idx_t end_idx = _cm->card_bitmap_index_for(obj_end);
|
||||||
|
|
||||||
// Set the bits in the card BM for this object (inclusive).
|
// Note: if we're looking at the last region in heap - obj_end
|
||||||
set_card_bitmap_range(start_idx, last_idx);
|
// could be actually just beyond the end of the heap; end_idx
|
||||||
|
// will then correspond to a (non-existent) card that is also
|
||||||
|
// just beyond the heap.
|
||||||
|
if (_g1h->is_in_g1_reserved(obj_end) && !_ct_bs->is_card_aligned(obj_end)) {
|
||||||
|
// end of object is not card aligned - increment to cover
|
||||||
|
// all the cards spanned by the object
|
||||||
|
end_idx += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the bits in the card BM for the cards spanned by this object.
|
||||||
|
_cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
|
||||||
|
|
||||||
// Add the size of this object to the number of marked bytes.
|
// Add the size of this object to the number of marked bytes.
|
||||||
marked_bytes += (size_t)obj_sz * HeapWordSize;
|
marked_bytes += (size_t)obj_sz * HeapWordSize;
|
||||||
|
|
||||||
// Find the next marked object after this one.
|
// Find the next marked object after this one.
|
||||||
start = _bm->getNextMarkedWordAddress(obj_last + 1, nextTop);
|
start = _bm->getNextMarkedWordAddress(obj_end, ntams);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the allocated-since-marking portion...
|
// Mark the allocated-since-marking portion...
|
||||||
HeapWord* top = hr->top();
|
HeapWord* top = hr->top();
|
||||||
if (nextTop < top) {
|
if (ntams < top) {
|
||||||
BitMap::idx_t start_idx = _cm->card_bitmap_index_for(nextTop);
|
BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams);
|
||||||
BitMap::idx_t last_idx = _cm->card_bitmap_index_for(top - 1);
|
BitMap::idx_t end_idx = _cm->card_bitmap_index_for(top);
|
||||||
|
|
||||||
set_card_bitmap_range(start_idx, last_idx);
|
// Note: if we're looking at the last region in heap - top
|
||||||
|
// could be actually just beyond the end of the heap; end_idx
|
||||||
|
// will then correspond to a (non-existent) card that is also
|
||||||
|
// just beyond the heap.
|
||||||
|
if (_g1h->is_in_g1_reserved(top) && !_ct_bs->is_card_aligned(top)) {
|
||||||
|
// end of object is not card aligned - increment to cover
|
||||||
|
// all the cards spanned by the object
|
||||||
|
end_idx += 1;
|
||||||
|
}
|
||||||
|
_cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
|
||||||
|
|
||||||
// This definitely means the region has live objects.
|
// This definitely means the region has live objects.
|
||||||
set_bit_for_region(hr);
|
set_bit_for_region(hr);
|
||||||
|
@ -1325,6 +1331,7 @@ public:
|
||||||
// regions during the STW cleanup pause.
|
// regions during the STW cleanup pause.
|
||||||
|
|
||||||
class VerifyLiveObjectDataHRClosure: public HeapRegionClosure {
|
class VerifyLiveObjectDataHRClosure: public HeapRegionClosure {
|
||||||
|
G1CollectedHeap* _g1h;
|
||||||
ConcurrentMark* _cm;
|
ConcurrentMark* _cm;
|
||||||
CalcLiveObjectsClosure _calc_cl;
|
CalcLiveObjectsClosure _calc_cl;
|
||||||
BitMap* _region_bm; // Region BM to be verified
|
BitMap* _region_bm; // Region BM to be verified
|
||||||
|
@ -1337,14 +1344,14 @@ class VerifyLiveObjectDataHRClosure: public HeapRegionClosure {
|
||||||
int _failures;
|
int _failures;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VerifyLiveObjectDataHRClosure(ConcurrentMark* cm,
|
VerifyLiveObjectDataHRClosure(G1CollectedHeap* g1h,
|
||||||
BitMap* region_bm,
|
BitMap* region_bm,
|
||||||
BitMap* card_bm,
|
BitMap* card_bm,
|
||||||
BitMap* exp_region_bm,
|
BitMap* exp_region_bm,
|
||||||
BitMap* exp_card_bm,
|
BitMap* exp_card_bm,
|
||||||
bool verbose) :
|
bool verbose) :
|
||||||
_cm(cm),
|
_g1h(g1h), _cm(g1h->concurrent_mark()),
|
||||||
_calc_cl(_cm->nextMarkBitMap(), _cm, exp_region_bm, exp_card_bm),
|
_calc_cl(_cm->nextMarkBitMap(), g1h, exp_region_bm, exp_card_bm),
|
||||||
_region_bm(region_bm), _card_bm(card_bm), _verbose(verbose),
|
_region_bm(region_bm), _card_bm(card_bm), _verbose(verbose),
|
||||||
_exp_region_bm(exp_region_bm), _exp_card_bm(exp_card_bm),
|
_exp_region_bm(exp_region_bm), _exp_card_bm(exp_card_bm),
|
||||||
_failures(0) { }
|
_failures(0) { }
|
||||||
|
@ -1491,7 +1498,7 @@ public:
|
||||||
void work(uint worker_id) {
|
void work(uint worker_id) {
|
||||||
assert(worker_id < _n_workers, "invariant");
|
assert(worker_id < _n_workers, "invariant");
|
||||||
|
|
||||||
VerifyLiveObjectDataHRClosure verify_cl(_cm,
|
VerifyLiveObjectDataHRClosure verify_cl(_g1h,
|
||||||
_actual_region_bm, _actual_card_bm,
|
_actual_region_bm, _actual_card_bm,
|
||||||
_expected_region_bm,
|
_expected_region_bm,
|
||||||
_expected_card_bm,
|
_expected_card_bm,
|
||||||
|
@ -1521,10 +1528,10 @@ public:
|
||||||
|
|
||||||
class FinalCountDataUpdateClosure: public CMCountDataClosureBase {
|
class FinalCountDataUpdateClosure: public CMCountDataClosureBase {
|
||||||
public:
|
public:
|
||||||
FinalCountDataUpdateClosure(ConcurrentMark* cm,
|
FinalCountDataUpdateClosure(G1CollectedHeap* g1h,
|
||||||
BitMap* region_bm,
|
BitMap* region_bm,
|
||||||
BitMap* card_bm) :
|
BitMap* card_bm) :
|
||||||
CMCountDataClosureBase(cm, region_bm, card_bm) { }
|
CMCountDataClosureBase(g1h, region_bm, card_bm) { }
|
||||||
|
|
||||||
bool doHeapRegion(HeapRegion* hr) {
|
bool doHeapRegion(HeapRegion* hr) {
|
||||||
|
|
||||||
|
@ -1548,24 +1555,29 @@ class FinalCountDataUpdateClosure: public CMCountDataClosureBase {
|
||||||
if (ntams < top) {
|
if (ntams < top) {
|
||||||
// This definitely means the region has live objects.
|
// This definitely means the region has live objects.
|
||||||
set_bit_for_region(hr);
|
set_bit_for_region(hr);
|
||||||
}
|
|
||||||
|
|
||||||
// Now set the bits for [ntams, top]
|
// Now set the bits in the card bitmap for [ntams, top)
|
||||||
BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams);
|
BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams);
|
||||||
// set_card_bitmap_range() expects the last_idx to be with
|
BitMap::idx_t end_idx = _cm->card_bitmap_index_for(top);
|
||||||
// the range of the bit map (see assertion in set_card_bitmap_range()),
|
|
||||||
// so limit it to that range with this application of MIN2.
|
// Note: if we're looking at the last region in heap - top
|
||||||
BitMap::idx_t last_idx = MIN2(_cm->card_bitmap_index_for(top),
|
// could be actually just beyond the end of the heap; end_idx
|
||||||
_card_bm->size()-1);
|
// will then correspond to a (non-existent) card that is also
|
||||||
if (start_idx < _card_bm->size()) {
|
// just beyond the heap.
|
||||||
set_card_bitmap_range(start_idx, last_idx);
|
if (_g1h->is_in_g1_reserved(top) && !_ct_bs->is_card_aligned(top)) {
|
||||||
} else {
|
// end of object is not card aligned - increment to cover
|
||||||
// To reach here start_idx must be beyond the end of
|
// all the cards spanned by the object
|
||||||
// the bit map and last_idx must have been limited by
|
end_idx += 1;
|
||||||
// the MIN2().
|
}
|
||||||
assert(start_idx == last_idx + 1,
|
|
||||||
err_msg("Not beyond end start_idx " SIZE_FORMAT " last_idx "
|
assert(end_idx <= _card_bm->size(),
|
||||||
SIZE_FORMAT, start_idx, last_idx));
|
err_msg("oob: end_idx= "SIZE_FORMAT", bitmap size= "SIZE_FORMAT,
|
||||||
|
end_idx, _card_bm->size()));
|
||||||
|
assert(start_idx < _card_bm->size(),
|
||||||
|
err_msg("oob: start_idx= "SIZE_FORMAT", bitmap size= "SIZE_FORMAT,
|
||||||
|
start_idx, _card_bm->size()));
|
||||||
|
|
||||||
|
_cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the bit for the region if it contains live data
|
// Set the bit for the region if it contains live data
|
||||||
|
@ -1606,7 +1618,7 @@ public:
|
||||||
void work(uint worker_id) {
|
void work(uint worker_id) {
|
||||||
assert(worker_id < _n_workers, "invariant");
|
assert(worker_id < _n_workers, "invariant");
|
||||||
|
|
||||||
FinalCountDataUpdateClosure final_update_cl(_cm,
|
FinalCountDataUpdateClosure final_update_cl(_g1h,
|
||||||
_actual_region_bm,
|
_actual_region_bm,
|
||||||
_actual_card_bm);
|
_actual_card_bm);
|
||||||
|
|
||||||
|
@ -2846,20 +2858,19 @@ void ConcurrentMark::clear_marking_state(bool clear_overflow) {
|
||||||
// Aggregate the counting data that was constructed concurrently
|
// Aggregate the counting data that was constructed concurrently
|
||||||
// with marking.
|
// with marking.
|
||||||
class AggregateCountDataHRClosure: public HeapRegionClosure {
|
class AggregateCountDataHRClosure: public HeapRegionClosure {
|
||||||
|
G1CollectedHeap* _g1h;
|
||||||
ConcurrentMark* _cm;
|
ConcurrentMark* _cm;
|
||||||
|
CardTableModRefBS* _ct_bs;
|
||||||
BitMap* _cm_card_bm;
|
BitMap* _cm_card_bm;
|
||||||
size_t _max_task_num;
|
size_t _max_task_num;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateCountDataHRClosure(ConcurrentMark *cm,
|
AggregateCountDataHRClosure(G1CollectedHeap* g1h,
|
||||||
BitMap* cm_card_bm,
|
BitMap* cm_card_bm,
|
||||||
size_t max_task_num) :
|
size_t max_task_num) :
|
||||||
_cm(cm), _cm_card_bm(cm_card_bm),
|
_g1h(g1h), _cm(g1h->concurrent_mark()),
|
||||||
_max_task_num(max_task_num) { }
|
_ct_bs((CardTableModRefBS*) (g1h->barrier_set())),
|
||||||
|
_cm_card_bm(cm_card_bm), _max_task_num(max_task_num) { }
|
||||||
bool is_card_aligned(HeapWord* p) {
|
|
||||||
return ((uintptr_t(p) & (CardTableModRefBS::card_size - 1)) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool doHeapRegion(HeapRegion* hr) {
|
bool doHeapRegion(HeapRegion* hr) {
|
||||||
if (hr->continuesHumongous()) {
|
if (hr->continuesHumongous()) {
|
||||||
|
@ -2890,16 +2901,23 @@ class AggregateCountDataHRClosure: public HeapRegionClosure {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(is_card_aligned(start), "sanity");
|
// 'start' should be in the heap.
|
||||||
assert(is_card_aligned(end), "sanity");
|
assert(_g1h->is_in_g1_reserved(start) && _ct_bs->is_card_aligned(start), "sanity");
|
||||||
|
// 'end' *may* be just beyone the end of the heap (if hr is the last region)
|
||||||
|
assert(!_g1h->is_in_g1_reserved(end) || _ct_bs->is_card_aligned(end), "sanity");
|
||||||
|
|
||||||
BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
|
BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
|
||||||
BitMap::idx_t limit_idx = _cm->card_bitmap_index_for(limit);
|
BitMap::idx_t limit_idx = _cm->card_bitmap_index_for(limit);
|
||||||
BitMap::idx_t end_idx = _cm->card_bitmap_index_for(end);
|
BitMap::idx_t end_idx = _cm->card_bitmap_index_for(end);
|
||||||
|
|
||||||
// If ntams is not card aligned then we bump the index for
|
// If ntams is not card aligned then we bump card bitmap index
|
||||||
// limit so that we get the card spanning ntams.
|
// for limit so that we get the all the cards spanned by
|
||||||
if (!is_card_aligned(limit)) {
|
// the object ending at ntams.
|
||||||
|
// Note: if this is the last region in the heap then ntams
|
||||||
|
// could be actually just beyond the end of the the heap;
|
||||||
|
// limit_idx will then correspond to a (non-existent) card
|
||||||
|
// that is also outside the heap.
|
||||||
|
if (_g1h->is_in_g1_reserved(limit) && !_ct_bs->is_card_aligned(limit)) {
|
||||||
limit_idx += 1;
|
limit_idx += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2928,7 +2946,7 @@ class AggregateCountDataHRClosure: public HeapRegionClosure {
|
||||||
|
|
||||||
// BitMap::get_next_one_offset() can handle the case when
|
// BitMap::get_next_one_offset() can handle the case when
|
||||||
// its left_offset parameter is greater than its right_offset
|
// its left_offset parameter is greater than its right_offset
|
||||||
// parameter. If does, however, have an early exit if
|
// parameter. It does, however, have an early exit if
|
||||||
// left_offset == right_offset. So let's limit the value
|
// left_offset == right_offset. So let's limit the value
|
||||||
// passed in for left offset here.
|
// passed in for left offset here.
|
||||||
BitMap::idx_t next_idx = MIN2(scan_idx + 1, limit_idx);
|
BitMap::idx_t next_idx = MIN2(scan_idx + 1, limit_idx);
|
||||||
|
@ -2964,7 +2982,7 @@ public:
|
||||||
_active_workers(n_workers) { }
|
_active_workers(n_workers) { }
|
||||||
|
|
||||||
void work(uint worker_id) {
|
void work(uint worker_id) {
|
||||||
AggregateCountDataHRClosure cl(_cm, _cm_card_bm, _max_task_num);
|
AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_task_num);
|
||||||
|
|
||||||
if (G1CollectedHeap::use_parallel_gc_threads()) {
|
if (G1CollectedHeap::use_parallel_gc_threads()) {
|
||||||
_g1h->heap_region_par_iterate_chunked(&cl, worker_id,
|
_g1h->heap_region_par_iterate_chunked(&cl, worker_id,
|
||||||
|
|
|
@ -806,7 +806,14 @@ public:
|
||||||
return _MARKING_VERBOSE_ && _verbose_level >= high_verbose;
|
return _MARKING_VERBOSE_ && _verbose_level >= high_verbose;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Counting data structure accessors
|
// Liveness counting
|
||||||
|
|
||||||
|
// Utility routine to set an exclusive range of cards on the given
|
||||||
|
// card liveness bitmap
|
||||||
|
inline void set_card_bitmap_range(BitMap* card_bm,
|
||||||
|
BitMap::idx_t start_idx,
|
||||||
|
BitMap::idx_t end_idx,
|
||||||
|
bool is_par);
|
||||||
|
|
||||||
// Returns the card number of the bottom of the G1 heap.
|
// Returns the card number of the bottom of the G1 heap.
|
||||||
// Used in biasing indices into accounting card bitmaps.
|
// Used in biasing indices into accounting card bitmaps.
|
||||||
|
|
|
@ -28,6 +28,42 @@
|
||||||
#include "gc_implementation/g1/concurrentMark.hpp"
|
#include "gc_implementation/g1/concurrentMark.hpp"
|
||||||
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
|
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
|
||||||
|
|
||||||
|
// Utility routine to set an exclusive range of cards on the given
|
||||||
|
// card liveness bitmap
|
||||||
|
inline void ConcurrentMark::set_card_bitmap_range(BitMap* card_bm,
|
||||||
|
BitMap::idx_t start_idx,
|
||||||
|
BitMap::idx_t end_idx,
|
||||||
|
bool is_par) {
|
||||||
|
|
||||||
|
// Set the exclusive bit range [start_idx, end_idx).
|
||||||
|
assert((end_idx - start_idx) > 0, "at least one card");
|
||||||
|
assert(end_idx <= card_bm->size(), "sanity");
|
||||||
|
|
||||||
|
// Silently clip the end index
|
||||||
|
end_idx = MIN2(end_idx, card_bm->size());
|
||||||
|
|
||||||
|
// For small ranges use a simple loop; otherwise use set_range or
|
||||||
|
// use par_at_put_range (if parallel). The range is made up of the
|
||||||
|
// cards that are spanned by an object/mem region so 8 cards will
|
||||||
|
// allow up to object sizes up to 4K to be handled using the loop.
|
||||||
|
if ((end_idx - start_idx) <= 8) {
|
||||||
|
for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
|
||||||
|
if (is_par) {
|
||||||
|
card_bm->par_set_bit(i);
|
||||||
|
} else {
|
||||||
|
card_bm->set_bit(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive.
|
||||||
|
if (is_par) {
|
||||||
|
card_bm->par_at_put_range(start_idx, end_idx, true);
|
||||||
|
} else {
|
||||||
|
card_bm->set_range(start_idx, end_idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the index in the liveness accounting card bitmap
|
// Returns the index in the liveness accounting card bitmap
|
||||||
// for the given address
|
// for the given address
|
||||||
inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
|
inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
|
||||||
|
@ -35,7 +71,6 @@ inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
|
||||||
// by the card shift -- address 0 corresponds to card number 0. One
|
// by the card shift -- address 0 corresponds to card number 0. One
|
||||||
// must subtract the card num of the bottom of the heap to obtain a
|
// must subtract the card num of the bottom of the heap to obtain a
|
||||||
// card table index.
|
// card table index.
|
||||||
|
|
||||||
intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
|
intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
|
||||||
return card_num - heap_bottom_card_num();
|
return card_num - heap_bottom_card_num();
|
||||||
}
|
}
|
||||||
|
@ -46,8 +81,10 @@ inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
|
||||||
size_t* marked_bytes_array,
|
size_t* marked_bytes_array,
|
||||||
BitMap* task_card_bm) {
|
BitMap* task_card_bm) {
|
||||||
G1CollectedHeap* g1h = _g1h;
|
G1CollectedHeap* g1h = _g1h;
|
||||||
|
CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set());
|
||||||
|
|
||||||
HeapWord* start = mr.start();
|
HeapWord* start = mr.start();
|
||||||
HeapWord* last = mr.last();
|
HeapWord* end = mr.end();
|
||||||
size_t region_size_bytes = mr.byte_size();
|
size_t region_size_bytes = mr.byte_size();
|
||||||
uint index = hr->hrs_index();
|
uint index = hr->hrs_index();
|
||||||
|
|
||||||
|
@ -61,24 +98,21 @@ inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
|
||||||
marked_bytes_array[index] += region_size_bytes;
|
marked_bytes_array[index] += region_size_bytes;
|
||||||
|
|
||||||
BitMap::idx_t start_idx = card_bitmap_index_for(start);
|
BitMap::idx_t start_idx = card_bitmap_index_for(start);
|
||||||
BitMap::idx_t last_idx = card_bitmap_index_for(last);
|
BitMap::idx_t end_idx = card_bitmap_index_for(end);
|
||||||
|
|
||||||
// The card bitmap is task/worker specific => no need to use 'par' routines.
|
// Note: if we're looking at the last region in heap - end
|
||||||
// Set bits in the inclusive bit range [start_idx, last_idx].
|
// could be actually just beyond the end of the heap; end_idx
|
||||||
//
|
// will then correspond to a (non-existent) card that is also
|
||||||
// For small ranges use a simple loop; otherwise use set_range
|
// just beyond the heap.
|
||||||
// The range are the cards that are spanned by the object/region
|
if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) {
|
||||||
// so 8 cards will allow objects/regions up to 4K to be handled
|
// end of region is not card aligned - incremement to cover
|
||||||
// using the loop.
|
// all the cards spanned by the region.
|
||||||
if ((last_idx - start_idx) <= 8) {
|
end_idx += 1;
|
||||||
for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
|
|
||||||
task_card_bm->set_bit(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assert(last_idx < task_card_bm->size(), "sanity");
|
|
||||||
// Note: BitMap::set_range() is exclusive.
|
|
||||||
task_card_bm->set_range(start_idx, last_idx+1);
|
|
||||||
}
|
}
|
||||||
|
// The card bitmap is task/worker specific => no need to use
|
||||||
|
// the 'par' BitMap routines.
|
||||||
|
// Set bits in the exclusive bit range [start_idx, end_idx).
|
||||||
|
set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Counts the given memory region in the task/worker counting
|
// Counts the given memory region in the task/worker counting
|
||||||
|
|
|
@ -4151,7 +4151,7 @@ void G1CollectedHeap::init_gc_alloc_regions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1CollectedHeap::release_gc_alloc_regions() {
|
void G1CollectedHeap::release_gc_alloc_regions(uint no_of_gc_workers) {
|
||||||
_survivor_gc_alloc_region.release();
|
_survivor_gc_alloc_region.release();
|
||||||
// If we have an old GC alloc region to release, we'll save it in
|
// If we have an old GC alloc region to release, we'll save it in
|
||||||
// _retained_old_gc_alloc_region. If we don't
|
// _retained_old_gc_alloc_region. If we don't
|
||||||
|
@ -4161,8 +4161,8 @@ void G1CollectedHeap::release_gc_alloc_regions() {
|
||||||
_retained_old_gc_alloc_region = _old_gc_alloc_region.release();
|
_retained_old_gc_alloc_region = _old_gc_alloc_region.release();
|
||||||
|
|
||||||
if (ResizePLAB) {
|
if (ResizePLAB) {
|
||||||
_survivor_plab_stats.adjust_desired_plab_sz();
|
_survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
|
||||||
_old_plab_stats.adjust_desired_plab_sz();
|
_old_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5427,7 +5427,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Weak Reference processing during an evacuation pause (part 1).
|
// Weak Reference processing during an evacuation pause (part 1).
|
||||||
void G1CollectedHeap::process_discovered_references() {
|
void G1CollectedHeap::process_discovered_references(uint no_of_gc_workers) {
|
||||||
double ref_proc_start = os::elapsedTime();
|
double ref_proc_start = os::elapsedTime();
|
||||||
|
|
||||||
ReferenceProcessor* rp = _ref_processor_stw;
|
ReferenceProcessor* rp = _ref_processor_stw;
|
||||||
|
@ -5454,15 +5454,14 @@ void G1CollectedHeap::process_discovered_references() {
|
||||||
// referents points to another object which is also referenced by an
|
// referents points to another object which is also referenced by an
|
||||||
// object discovered by the STW ref processor.
|
// object discovered by the STW ref processor.
|
||||||
|
|
||||||
uint active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
|
|
||||||
workers()->active_workers() : 1);
|
|
||||||
|
|
||||||
assert(!G1CollectedHeap::use_parallel_gc_threads() ||
|
assert(!G1CollectedHeap::use_parallel_gc_threads() ||
|
||||||
active_workers == workers()->active_workers(),
|
no_of_gc_workers == workers()->active_workers(),
|
||||||
"Need to reset active_workers");
|
"Need to reset active GC workers");
|
||||||
|
|
||||||
set_par_threads(active_workers);
|
set_par_threads(no_of_gc_workers);
|
||||||
G1ParPreserveCMReferentsTask keep_cm_referents(this, active_workers, _task_queues);
|
G1ParPreserveCMReferentsTask keep_cm_referents(this,
|
||||||
|
no_of_gc_workers,
|
||||||
|
_task_queues);
|
||||||
|
|
||||||
if (G1CollectedHeap::use_parallel_gc_threads()) {
|
if (G1CollectedHeap::use_parallel_gc_threads()) {
|
||||||
workers()->run_task(&keep_cm_referents);
|
workers()->run_task(&keep_cm_referents);
|
||||||
|
@ -5528,10 +5527,10 @@ void G1CollectedHeap::process_discovered_references() {
|
||||||
NULL);
|
NULL);
|
||||||
} else {
|
} else {
|
||||||
// Parallel reference processing
|
// Parallel reference processing
|
||||||
assert(rp->num_q() == active_workers, "sanity");
|
assert(rp->num_q() == no_of_gc_workers, "sanity");
|
||||||
assert(active_workers <= rp->max_num_q(), "sanity");
|
assert(no_of_gc_workers <= rp->max_num_q(), "sanity");
|
||||||
|
|
||||||
G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, active_workers);
|
G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, no_of_gc_workers);
|
||||||
rp->process_discovered_references(&is_alive, &keep_alive, &drain_queue, &par_task_executor);
|
rp->process_discovered_references(&is_alive, &keep_alive, &drain_queue, &par_task_executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5546,7 +5545,7 @@ void G1CollectedHeap::process_discovered_references() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Weak Reference processing during an evacuation pause (part 2).
|
// Weak Reference processing during an evacuation pause (part 2).
|
||||||
void G1CollectedHeap::enqueue_discovered_references() {
|
void G1CollectedHeap::enqueue_discovered_references(uint no_of_gc_workers) {
|
||||||
double ref_enq_start = os::elapsedTime();
|
double ref_enq_start = os::elapsedTime();
|
||||||
|
|
||||||
ReferenceProcessor* rp = _ref_processor_stw;
|
ReferenceProcessor* rp = _ref_processor_stw;
|
||||||
|
@ -5560,13 +5559,12 @@ void G1CollectedHeap::enqueue_discovered_references() {
|
||||||
} else {
|
} else {
|
||||||
// Parallel reference enqueuing
|
// Parallel reference enqueuing
|
||||||
|
|
||||||
uint active_workers = (ParallelGCThreads > 0 ? workers()->active_workers() : 1);
|
assert(no_of_gc_workers == workers()->active_workers(),
|
||||||
assert(active_workers == workers()->active_workers(),
|
"Need to reset active workers");
|
||||||
"Need to reset active_workers");
|
assert(rp->num_q() == no_of_gc_workers, "sanity");
|
||||||
assert(rp->num_q() == active_workers, "sanity");
|
assert(no_of_gc_workers <= rp->max_num_q(), "sanity");
|
||||||
assert(active_workers <= rp->max_num_q(), "sanity");
|
|
||||||
|
|
||||||
G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, active_workers);
|
G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, no_of_gc_workers);
|
||||||
rp->enqueue_discovered_references(&par_task_executor);
|
rp->enqueue_discovered_references(&par_task_executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5658,7 +5656,7 @@ void G1CollectedHeap::evacuate_collection_set() {
|
||||||
// as we may have to copy some 'reachable' referent
|
// as we may have to copy some 'reachable' referent
|
||||||
// objects (and their reachable sub-graphs) that were
|
// objects (and their reachable sub-graphs) that were
|
||||||
// not copied during the pause.
|
// not copied during the pause.
|
||||||
process_discovered_references();
|
process_discovered_references(n_workers);
|
||||||
|
|
||||||
// Weak root processing.
|
// Weak root processing.
|
||||||
// Note: when JSR 292 is enabled and code blobs can contain
|
// Note: when JSR 292 is enabled and code blobs can contain
|
||||||
|
@ -5670,7 +5668,7 @@ void G1CollectedHeap::evacuate_collection_set() {
|
||||||
JNIHandles::weak_oops_do(&is_alive, &keep_alive);
|
JNIHandles::weak_oops_do(&is_alive, &keep_alive);
|
||||||
}
|
}
|
||||||
|
|
||||||
release_gc_alloc_regions();
|
release_gc_alloc_regions(n_workers);
|
||||||
g1_rem_set()->cleanup_after_oops_into_collection_set_do();
|
g1_rem_set()->cleanup_after_oops_into_collection_set_do();
|
||||||
|
|
||||||
concurrent_g1_refine()->clear_hot_cache();
|
concurrent_g1_refine()->clear_hot_cache();
|
||||||
|
@ -5694,7 +5692,7 @@ void G1CollectedHeap::evacuate_collection_set() {
|
||||||
// will log these updates (and dirty their associated
|
// will log these updates (and dirty their associated
|
||||||
// cards). We need these updates logged to update any
|
// cards). We need these updates logged to update any
|
||||||
// RSets.
|
// RSets.
|
||||||
enqueue_discovered_references();
|
enqueue_discovered_references(n_workers);
|
||||||
|
|
||||||
if (G1DeferredRSUpdate) {
|
if (G1DeferredRSUpdate) {
|
||||||
RedirtyLoggedCardTableEntryFastClosure redirty;
|
RedirtyLoggedCardTableEntryFastClosure redirty;
|
||||||
|
|
|
@ -326,7 +326,7 @@ private:
|
||||||
void init_gc_alloc_regions();
|
void init_gc_alloc_regions();
|
||||||
|
|
||||||
// It releases the GC alloc regions at the end of a GC.
|
// It releases the GC alloc regions at the end of a GC.
|
||||||
void release_gc_alloc_regions();
|
void release_gc_alloc_regions(uint no_of_gc_workers);
|
||||||
|
|
||||||
// It does any cleanup that needs to be done on the GC alloc regions
|
// It does any cleanup that needs to be done on the GC alloc regions
|
||||||
// before a Full GC.
|
// before a Full GC.
|
||||||
|
@ -652,11 +652,11 @@ protected:
|
||||||
|
|
||||||
// Process any reference objects discovered during
|
// Process any reference objects discovered during
|
||||||
// an incremental evacuation pause.
|
// an incremental evacuation pause.
|
||||||
void process_discovered_references();
|
void process_discovered_references(uint no_of_gc_workers);
|
||||||
|
|
||||||
// Enqueue any remaining discovered references
|
// Enqueue any remaining discovered references
|
||||||
// after processing.
|
// after processing.
|
||||||
void enqueue_discovered_references();
|
void enqueue_discovered_references(uint no_of_gc_workers);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -840,8 +840,8 @@ private:
|
||||||
//
|
//
|
||||||
|
|
||||||
// Current tenuring threshold, set to 0 if the collector reaches the
|
// Current tenuring threshold, set to 0 if the collector reaches the
|
||||||
// maximum amount of suvivors regions.
|
// maximum amount of survivors regions.
|
||||||
int _tenuring_threshold;
|
uint _tenuring_threshold;
|
||||||
|
|
||||||
// The limit on the number of regions allocated for survivors.
|
// The limit on the number of regions allocated for survivors.
|
||||||
uint _max_survivor_regions;
|
uint _max_survivor_regions;
|
||||||
|
@ -851,7 +851,7 @@ private:
|
||||||
size_t _survivor_bytes_before_gc;
|
size_t _survivor_bytes_before_gc;
|
||||||
size_t _capacity_before_gc;
|
size_t _capacity_before_gc;
|
||||||
|
|
||||||
// The amount of survor regions after a collection.
|
// The amount of survivor regions after a collection.
|
||||||
uint _recorded_survivor_regions;
|
uint _recorded_survivor_regions;
|
||||||
// List of survivor regions.
|
// List of survivor regions.
|
||||||
HeapRegion* _recorded_survivor_head;
|
HeapRegion* _recorded_survivor_head;
|
||||||
|
@ -862,7 +862,7 @@ private:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline GCAllocPurpose
|
inline GCAllocPurpose
|
||||||
evacuation_destination(HeapRegion* src_region, int age, size_t word_sz) {
|
evacuation_destination(HeapRegion* src_region, uint age, size_t word_sz) {
|
||||||
if (age < _tenuring_threshold && src_region->is_young()) {
|
if (age < _tenuring_threshold && src_region->is_young()) {
|
||||||
return GCAllocForSurvived;
|
return GCAllocForSurvived;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1037,7 +1037,7 @@ void ParNewGeneration::collect(bool full,
|
||||||
|
|
||||||
adjust_desired_tenuring_threshold();
|
adjust_desired_tenuring_threshold();
|
||||||
if (ResizePLAB) {
|
if (ResizePLAB) {
|
||||||
plab_stats()->adjust_desired_plab_sz();
|
plab_stats()->adjust_desired_plab_sz(n_workers);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PrintGC && !PrintGCDetails) {
|
if (PrintGC && !PrintGCDetails) {
|
||||||
|
|
|
@ -121,103 +121,12 @@ class CheckForPreciseMarks : public OopClosure {
|
||||||
|
|
||||||
// We get passed the space_top value to prevent us from traversing into
|
// We get passed the space_top value to prevent us from traversing into
|
||||||
// the old_gen promotion labs, which cannot be safely parsed.
|
// the old_gen promotion labs, which cannot be safely parsed.
|
||||||
void CardTableExtension::scavenge_contents(ObjectStartArray* start_array,
|
|
||||||
MutableSpace* sp,
|
|
||||||
HeapWord* space_top,
|
|
||||||
PSPromotionManager* pm)
|
|
||||||
{
|
|
||||||
assert(start_array != NULL && sp != NULL && pm != NULL, "Sanity");
|
|
||||||
assert(start_array->covered_region().contains(sp->used_region()),
|
|
||||||
"ObjectStartArray does not cover space");
|
|
||||||
|
|
||||||
if (sp->not_empty()) {
|
// Do not call this method if the space is empty.
|
||||||
oop* sp_top = (oop*)space_top;
|
// It is a waste to start tasks and get here only to
|
||||||
oop* prev_top = NULL;
|
// do no work. If this method needs to be called
|
||||||
jbyte* current_card = byte_for(sp->bottom());
|
// when the space is empty, fix the calculation of
|
||||||
jbyte* end_card = byte_for(sp_top - 1); // sp_top is exclusive
|
// end_card to allow sp_top == sp->bottom().
|
||||||
// scan card marking array
|
|
||||||
while (current_card <= end_card) {
|
|
||||||
jbyte value = *current_card;
|
|
||||||
// skip clean cards
|
|
||||||
if (card_is_clean(value)) {
|
|
||||||
current_card++;
|
|
||||||
} else {
|
|
||||||
// we found a non-clean card
|
|
||||||
jbyte* first_nonclean_card = current_card++;
|
|
||||||
oop* bottom = (oop*)addr_for(first_nonclean_card);
|
|
||||||
// find object starting on card
|
|
||||||
oop* bottom_obj = (oop*)start_array->object_start((HeapWord*)bottom);
|
|
||||||
// bottom_obj = (oop*)start_array->object_start((HeapWord*)bottom);
|
|
||||||
assert(bottom_obj <= bottom, "just checking");
|
|
||||||
// make sure we don't scan oops we already looked at
|
|
||||||
if (bottom < prev_top) bottom = prev_top;
|
|
||||||
// figure out when to stop scanning
|
|
||||||
jbyte* first_clean_card;
|
|
||||||
oop* top;
|
|
||||||
bool restart_scanning;
|
|
||||||
do {
|
|
||||||
restart_scanning = false;
|
|
||||||
// find a clean card
|
|
||||||
while (current_card <= end_card) {
|
|
||||||
value = *current_card;
|
|
||||||
if (card_is_clean(value)) break;
|
|
||||||
current_card++;
|
|
||||||
}
|
|
||||||
// check if we reached the end, if so we are done
|
|
||||||
if (current_card >= end_card) {
|
|
||||||
first_clean_card = end_card + 1;
|
|
||||||
current_card++;
|
|
||||||
top = sp_top;
|
|
||||||
} else {
|
|
||||||
// we have a clean card, find object starting on that card
|
|
||||||
first_clean_card = current_card++;
|
|
||||||
top = (oop*)addr_for(first_clean_card);
|
|
||||||
oop* top_obj = (oop*)start_array->object_start((HeapWord*)top);
|
|
||||||
// top_obj = (oop*)start_array->object_start((HeapWord*)top);
|
|
||||||
assert(top_obj <= top, "just checking");
|
|
||||||
if (oop(top_obj)->is_objArray() || oop(top_obj)->is_typeArray()) {
|
|
||||||
// an arrayOop is starting on the clean card - since we do exact store
|
|
||||||
// checks for objArrays we are done
|
|
||||||
} else {
|
|
||||||
// otherwise, it is possible that the object starting on the clean card
|
|
||||||
// spans the entire card, and that the store happened on a later card.
|
|
||||||
// figure out where the object ends
|
|
||||||
top = top_obj + oop(top_obj)->size();
|
|
||||||
jbyte* top_card = CardTableModRefBS::byte_for(top - 1); // top is exclusive
|
|
||||||
if (top_card > first_clean_card) {
|
|
||||||
// object ends a different card
|
|
||||||
current_card = top_card + 1;
|
|
||||||
if (card_is_clean(*top_card)) {
|
|
||||||
// the ending card is clean, we are done
|
|
||||||
first_clean_card = top_card;
|
|
||||||
} else {
|
|
||||||
// the ending card is not clean, continue scanning at start of do-while
|
|
||||||
restart_scanning = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// object ends on the clean card, we are done.
|
|
||||||
assert(first_clean_card == top_card, "just checking");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (restart_scanning);
|
|
||||||
// we know which cards to scan, now clear them
|
|
||||||
while (first_nonclean_card < first_clean_card) {
|
|
||||||
*first_nonclean_card++ = clean_card;
|
|
||||||
}
|
|
||||||
// scan oops in objects
|
|
||||||
do {
|
|
||||||
oop(bottom_obj)->push_contents(pm);
|
|
||||||
bottom_obj += oop(bottom_obj)->size();
|
|
||||||
assert(bottom_obj <= sp_top, "just checking");
|
|
||||||
} while (bottom_obj < top);
|
|
||||||
pm->drain_stacks_cond_depth();
|
|
||||||
// remember top oop* scanned
|
|
||||||
prev_top = top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_array,
|
void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_array,
|
||||||
MutableSpace* sp,
|
MutableSpace* sp,
|
||||||
|
@ -228,10 +137,11 @@ void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_arra
|
||||||
int ssize = 128; // Naked constant! Work unit = 64k.
|
int ssize = 128; // Naked constant! Work unit = 64k.
|
||||||
int dirty_card_count = 0;
|
int dirty_card_count = 0;
|
||||||
|
|
||||||
|
// It is a waste to get here if empty.
|
||||||
|
assert(sp->bottom() < sp->top(), "Should not be called if empty");
|
||||||
oop* sp_top = (oop*)space_top;
|
oop* sp_top = (oop*)space_top;
|
||||||
oop* sp_last = sp->bottom() == space_top ? sp_top : sp_top - 1;
|
|
||||||
jbyte* start_card = byte_for(sp->bottom());
|
jbyte* start_card = byte_for(sp->bottom());
|
||||||
jbyte* end_card = byte_for(sp_last) + 1;
|
jbyte* end_card = byte_for(sp_top - 1) + 1;
|
||||||
oop* last_scanned = NULL; // Prevent scanning objects more than once
|
oop* last_scanned = NULL; // Prevent scanning objects more than once
|
||||||
// The width of the stripe ssize*stripe_total must be
|
// The width of the stripe ssize*stripe_total must be
|
||||||
// consistent with the number of stripes so that the complete slice
|
// consistent with the number of stripes so that the complete slice
|
||||||
|
@ -255,6 +165,16 @@ void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_arra
|
||||||
HeapWord* slice_start = addr_for(worker_start_card);
|
HeapWord* slice_start = addr_for(worker_start_card);
|
||||||
HeapWord* slice_end = MIN2((HeapWord*) sp_top, addr_for(worker_end_card));
|
HeapWord* slice_end = MIN2((HeapWord*) sp_top, addr_for(worker_end_card));
|
||||||
|
|
||||||
|
#ifdef ASSERT
|
||||||
|
if (GCWorkerDelayMillis > 0) {
|
||||||
|
// Delay 1 worker so that it proceeds after all the work
|
||||||
|
// has been completed.
|
||||||
|
if (stripe_number < 2) {
|
||||||
|
os::sleep(Thread::current(), GCWorkerDelayMillis, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// If there are not objects starting within the chunk, skip it.
|
// If there are not objects starting within the chunk, skip it.
|
||||||
if (!start_array->object_starts_in_range(slice_start, slice_end)) {
|
if (!start_array->object_starts_in_range(slice_start, slice_end)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -60,11 +60,6 @@ class CardTableExtension : public CardTableModRefBS {
|
||||||
// BarrierSet::Name kind() { return BarrierSet::CardTableExtension; }
|
// BarrierSet::Name kind() { return BarrierSet::CardTableExtension; }
|
||||||
|
|
||||||
// Scavenge support
|
// Scavenge support
|
||||||
void scavenge_contents(ObjectStartArray* start_array,
|
|
||||||
MutableSpace* sp,
|
|
||||||
HeapWord* space_top,
|
|
||||||
PSPromotionManager* pm);
|
|
||||||
|
|
||||||
void scavenge_contents_parallel(ObjectStartArray* start_array,
|
void scavenge_contents_parallel(ObjectStartArray* start_array,
|
||||||
MutableSpace* sp,
|
MutableSpace* sp,
|
||||||
HeapWord* space_top,
|
HeapWord* space_top,
|
||||||
|
|
|
@ -941,9 +941,9 @@ size_t PSAdaptiveSizePolicy::promo_decrement(size_t cur_promo) {
|
||||||
return promo_heap_delta;
|
return promo_heap_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
|
uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
|
||||||
bool is_survivor_overflow,
|
bool is_survivor_overflow,
|
||||||
int tenuring_threshold,
|
uint tenuring_threshold,
|
||||||
size_t survivor_limit) {
|
size_t survivor_limit) {
|
||||||
assert(survivor_limit >= _intra_generation_alignment,
|
assert(survivor_limit >= _intra_generation_alignment,
|
||||||
"survivor_limit too small");
|
"survivor_limit too small");
|
||||||
|
|
|
@ -353,9 +353,9 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
|
||||||
|
|
||||||
// Calculates new survivor space size; returns a new tenuring threshold
|
// Calculates new survivor space size; returns a new tenuring threshold
|
||||||
// value. Stores new survivor size in _survivor_size.
|
// value. Stores new survivor size in _survivor_size.
|
||||||
int compute_survivor_space_size_and_threshold(bool is_survivor_overflow,
|
uint compute_survivor_space_size_and_threshold(bool is_survivor_overflow,
|
||||||
int tenuring_threshold,
|
uint tenuring_threshold,
|
||||||
size_t survivor_limit);
|
size_t survivor_limit);
|
||||||
|
|
||||||
// Return the maximum size of a survivor space if the young generation were of
|
// Return the maximum size of a survivor space if the young generation were of
|
||||||
// size gen_size.
|
// size gen_size.
|
||||||
|
|
|
@ -85,7 +85,7 @@ oop PSPromotionManager::copy_to_survivor_space(oop o) {
|
||||||
|
|
||||||
if (!promote_immediately) {
|
if (!promote_immediately) {
|
||||||
// Find the objects age, MT safe.
|
// Find the objects age, MT safe.
|
||||||
int age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
|
uint age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
|
||||||
test_mark->displaced_mark_helper()->age() : test_mark->age();
|
test_mark->displaced_mark_helper()->age() : test_mark->age();
|
||||||
|
|
||||||
// Try allocating obj in to-space (unless too old)
|
// Try allocating obj in to-space (unless too old)
|
||||||
|
@ -136,6 +136,13 @@ oop PSPromotionManager::copy_to_survivor_space(oop o) {
|
||||||
|
|
||||||
HeapWord* lab_base = old_gen()->cas_allocate(OldPLABSize);
|
HeapWord* lab_base = old_gen()->cas_allocate(OldPLABSize);
|
||||||
if(lab_base != NULL) {
|
if(lab_base != NULL) {
|
||||||
|
#ifdef ASSERT
|
||||||
|
// Delay the initialization of the promotion lab (plab).
|
||||||
|
// This exposes uninitialized plabs to card table processing.
|
||||||
|
if (GCWorkerDelayMillis > 0) {
|
||||||
|
os::sleep(Thread::current(), GCWorkerDelayMillis, false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
_old_lab.initialize(MemRegion(lab_base, OldPLABSize));
|
_old_lab.initialize(MemRegion(lab_base, OldPLABSize));
|
||||||
// Try the old lab allocation again.
|
// Try the old lab allocation again.
|
||||||
new_obj = (oop) _old_lab.allocate(new_obj_size);
|
new_obj = (oop) _old_lab.allocate(new_obj_size);
|
||||||
|
|
|
@ -59,7 +59,7 @@ int PSScavenge::_consecutive_skipped_scavenges = 0;
|
||||||
ReferenceProcessor* PSScavenge::_ref_processor = NULL;
|
ReferenceProcessor* PSScavenge::_ref_processor = NULL;
|
||||||
CardTableExtension* PSScavenge::_card_table = NULL;
|
CardTableExtension* PSScavenge::_card_table = NULL;
|
||||||
bool PSScavenge::_survivor_overflow = false;
|
bool PSScavenge::_survivor_overflow = false;
|
||||||
int PSScavenge::_tenuring_threshold = 0;
|
uint PSScavenge::_tenuring_threshold = 0;
|
||||||
HeapWord* PSScavenge::_young_generation_boundary = NULL;
|
HeapWord* PSScavenge::_young_generation_boundary = NULL;
|
||||||
elapsedTimer PSScavenge::_accumulated_time;
|
elapsedTimer PSScavenge::_accumulated_time;
|
||||||
Stack<markOop, mtGC> PSScavenge::_preserved_mark_stack;
|
Stack<markOop, mtGC> PSScavenge::_preserved_mark_stack;
|
||||||
|
@ -395,9 +395,13 @@ bool PSScavenge::invoke_no_policy() {
|
||||||
|
|
||||||
GCTaskQueue* q = GCTaskQueue::create();
|
GCTaskQueue* q = GCTaskQueue::create();
|
||||||
|
|
||||||
uint stripe_total = active_workers;
|
if (!old_gen->object_space()->is_empty()) {
|
||||||
for(uint i=0; i < stripe_total; i++) {
|
// There are only old-to-young pointers if there are objects
|
||||||
q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i, stripe_total));
|
// in the old gen.
|
||||||
|
uint stripe_total = active_workers;
|
||||||
|
for(uint i=0; i < stripe_total; i++) {
|
||||||
|
q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i, stripe_total));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe));
|
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe));
|
||||||
|
@ -525,7 +529,7 @@ bool PSScavenge::invoke_no_policy() {
|
||||||
|
|
||||||
if (PrintTenuringDistribution) {
|
if (PrintTenuringDistribution) {
|
||||||
gclog_or_tty->cr();
|
gclog_or_tty->cr();
|
||||||
gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %d (max %d)",
|
gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %u (max %u)",
|
||||||
size_policy->calculated_survivor_size_in_bytes(),
|
size_policy->calculated_survivor_size_in_bytes(),
|
||||||
_tenuring_threshold, MaxTenuringThreshold);
|
_tenuring_threshold, MaxTenuringThreshold);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,14 +66,14 @@ class PSScavenge: AllStatic {
|
||||||
static PSIsAliveClosure _is_alive_closure; // Closure used for reference processing
|
static PSIsAliveClosure _is_alive_closure; // Closure used for reference processing
|
||||||
static CardTableExtension* _card_table; // We cache the card table for fast access.
|
static CardTableExtension* _card_table; // We cache the card table for fast access.
|
||||||
static bool _survivor_overflow; // Overflow this collection
|
static bool _survivor_overflow; // Overflow this collection
|
||||||
static int _tenuring_threshold; // tenuring threshold for next scavenge
|
static uint _tenuring_threshold; // tenuring threshold for next scavenge
|
||||||
static elapsedTimer _accumulated_time; // total time spent on scavenge
|
static elapsedTimer _accumulated_time; // total time spent on scavenge
|
||||||
static HeapWord* _young_generation_boundary; // The lowest address possible for the young_gen.
|
static HeapWord* _young_generation_boundary; // The lowest address possible for the young_gen.
|
||||||
// This is used to decide if an oop should be scavenged,
|
// This is used to decide if an oop should be scavenged,
|
||||||
// cards should be marked, etc.
|
// cards should be marked, etc.
|
||||||
static Stack<markOop, mtGC> _preserved_mark_stack; // List of marks to be restored after failed promotion
|
static Stack<markOop, mtGC> _preserved_mark_stack; // List of marks to be restored after failed promotion
|
||||||
static Stack<oop, mtGC> _preserved_oop_stack; // List of oops that need their mark restored.
|
static Stack<oop, mtGC> _preserved_oop_stack; // List of oops that need their mark restored.
|
||||||
static CollectorCounters* _counters; // collector performance counters
|
static CollectorCounters* _counters; // collector performance counters
|
||||||
static bool _promotion_failed;
|
static bool _promotion_failed;
|
||||||
|
|
||||||
static void clean_up_failed_promotion();
|
static void clean_up_failed_promotion();
|
||||||
|
@ -88,7 +88,7 @@ class PSScavenge: AllStatic {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Accessors
|
// Accessors
|
||||||
static int tenuring_threshold() { return _tenuring_threshold; }
|
static uint tenuring_threshold() { return _tenuring_threshold; }
|
||||||
static elapsedTimer* accumulated_time() { return &_accumulated_time; }
|
static elapsedTimer* accumulated_time() { return &_accumulated_time; }
|
||||||
static bool promotion_failed() { return _promotion_failed; }
|
static bool promotion_failed() { return _promotion_failed; }
|
||||||
static int consecutive_skipped_scavenges()
|
static int consecutive_skipped_scavenges()
|
||||||
|
|
|
@ -164,36 +164,14 @@ void StealTask::do_it(GCTaskManager* manager, uint which) {
|
||||||
guarantee(pm->stacks_empty(), "stacks should be empty at this point");
|
guarantee(pm->stacks_empty(), "stacks should be empty at this point");
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// SerialOldToYoungRootsTask
|
|
||||||
//
|
|
||||||
|
|
||||||
void SerialOldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
|
|
||||||
assert(_gen != NULL, "Sanity");
|
|
||||||
assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
|
|
||||||
|
|
||||||
{
|
|
||||||
PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
|
|
||||||
|
|
||||||
assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
|
|
||||||
CardTableExtension* card_table = (CardTableExtension *)Universe::heap()->barrier_set();
|
|
||||||
// FIX ME! Assert that card_table is the type we believe it to be.
|
|
||||||
|
|
||||||
card_table->scavenge_contents(_gen->start_array(),
|
|
||||||
_gen->object_space(),
|
|
||||||
_gen_top,
|
|
||||||
pm);
|
|
||||||
|
|
||||||
// Do the real work
|
|
||||||
pm->drain_stacks(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// OldToYoungRootsTask
|
// OldToYoungRootsTask
|
||||||
//
|
//
|
||||||
|
|
||||||
void OldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
|
void OldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
|
||||||
|
// There are not old-to-young pointers if the old gen is empty.
|
||||||
|
assert(!_gen->object_space()->is_empty(),
|
||||||
|
"Should not be called is there is no work");
|
||||||
assert(_gen != NULL, "Sanity");
|
assert(_gen != NULL, "Sanity");
|
||||||
assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
|
assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
|
||||||
assert(_stripe_number < ParallelGCThreads, "Sanity");
|
assert(_stripe_number < ParallelGCThreads, "Sanity");
|
||||||
|
|
|
@ -112,25 +112,6 @@ class StealTask : public GCTask {
|
||||||
virtual void do_it(GCTaskManager* manager, uint which);
|
virtual void do_it(GCTaskManager* manager, uint which);
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
|
||||||
// SerialOldToYoungRootsTask
|
|
||||||
//
|
|
||||||
// This task is used to scan for roots in the perm gen
|
|
||||||
|
|
||||||
class SerialOldToYoungRootsTask : public GCTask {
|
|
||||||
private:
|
|
||||||
PSOldGen* _gen;
|
|
||||||
HeapWord* _gen_top;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SerialOldToYoungRootsTask(PSOldGen *gen, HeapWord* gen_top) :
|
|
||||||
_gen(gen), _gen_top(gen_top) { }
|
|
||||||
|
|
||||||
char* name() { return (char *)"serial-old-to-young-roots-task"; }
|
|
||||||
|
|
||||||
virtual void do_it(GCTaskManager* manager, uint which);
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// OldToYoungRootsTask
|
// OldToYoungRootsTask
|
||||||
//
|
//
|
||||||
|
|
|
@ -642,7 +642,7 @@ bool AdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) const {
|
||||||
|
|
||||||
bool AdaptiveSizePolicy::print_adaptive_size_policy_on(
|
bool AdaptiveSizePolicy::print_adaptive_size_policy_on(
|
||||||
outputStream* st,
|
outputStream* st,
|
||||||
int tenuring_threshold_arg) const {
|
uint tenuring_threshold_arg) const {
|
||||||
if (!AdaptiveSizePolicy::print_adaptive_size_policy_on(st)) {
|
if (!AdaptiveSizePolicy::print_adaptive_size_policy_on(st)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -663,7 +663,7 @@ bool AdaptiveSizePolicy::print_adaptive_size_policy_on(
|
||||||
assert(!tenuring_threshold_change(), "(no change was attempted)");
|
assert(!tenuring_threshold_change(), "(no change was attempted)");
|
||||||
}
|
}
|
||||||
if (tenuring_threshold_changed) {
|
if (tenuring_threshold_changed) {
|
||||||
st->print_cr("%d", tenuring_threshold_arg);
|
st->print_cr("%u", tenuring_threshold_arg);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -489,8 +489,8 @@ class AdaptiveSizePolicy : public CHeapObj<mtGC> {
|
||||||
|
|
||||||
// Printing support
|
// Printing support
|
||||||
virtual bool print_adaptive_size_policy_on(outputStream* st) const;
|
virtual bool print_adaptive_size_policy_on(outputStream* st) const;
|
||||||
bool print_adaptive_size_policy_on(outputStream* st, int
|
bool print_adaptive_size_policy_on(outputStream* st,
|
||||||
tenuring_threshold) const;
|
uint tenuring_threshold) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Class that can be used to print information about the
|
// Class that can be used to print information about the
|
||||||
|
|
|
@ -78,10 +78,10 @@ void ageTable::merge_par(ageTable* subTable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
|
uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
|
||||||
size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
|
size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
int age = 1;
|
uint age = 1;
|
||||||
assert(sizes[0] == 0, "no objects with age zero should be recorded");
|
assert(sizes[0] == 0, "no objects with age zero should be recorded");
|
||||||
while (age < table_size) {
|
while (age < table_size) {
|
||||||
total += sizes[age];
|
total += sizes[age];
|
||||||
|
@ -90,13 +90,13 @@ int ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
|
||||||
if (total > desired_survivor_size) break;
|
if (total > desired_survivor_size) break;
|
||||||
age++;
|
age++;
|
||||||
}
|
}
|
||||||
int result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
|
uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
|
||||||
|
|
||||||
if (PrintTenuringDistribution || UsePerfData) {
|
if (PrintTenuringDistribution || UsePerfData) {
|
||||||
|
|
||||||
if (PrintTenuringDistribution) {
|
if (PrintTenuringDistribution) {
|
||||||
gclog_or_tty->cr();
|
gclog_or_tty->cr();
|
||||||
gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %d (max %d)",
|
gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %u (max %u)",
|
||||||
desired_survivor_size*oopSize, result, MaxTenuringThreshold);
|
desired_survivor_size*oopSize, result, MaxTenuringThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ int ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
|
||||||
total += sizes[age];
|
total += sizes[age];
|
||||||
if (sizes[age] > 0) {
|
if (sizes[age] > 0) {
|
||||||
if (PrintTenuringDistribution) {
|
if (PrintTenuringDistribution) {
|
||||||
gclog_or_tty->print_cr("- age %3d: %10ld bytes, %10ld total",
|
gclog_or_tty->print_cr("- age %3u: %10ld bytes, %10ld total",
|
||||||
age, sizes[age]*oopSize, total*oopSize);
|
age, sizes[age]*oopSize, total*oopSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ class ageTable VALUE_OBJ_CLASS_SPEC {
|
||||||
|
|
||||||
// add entry
|
// add entry
|
||||||
void add(oop p, size_t oop_size) {
|
void add(oop p, size_t oop_size) {
|
||||||
int age = p->age();
|
uint age = p->age();
|
||||||
assert(age > 0 && age < table_size, "invalid age of object");
|
assert(age > 0 && age < table_size, "invalid age of object");
|
||||||
sizes[age] += oop_size;
|
sizes[age] += oop_size;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ class ageTable VALUE_OBJ_CLASS_SPEC {
|
||||||
void merge_par(ageTable* subTable);
|
void merge_par(ageTable* subTable);
|
||||||
|
|
||||||
// calculate new tenuring threshold based on age information
|
// calculate new tenuring threshold based on age information
|
||||||
int compute_tenuring_threshold(size_t survivor_capacity);
|
uint compute_tenuring_threshold(size_t survivor_capacity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PerfVariable* _perf_sizes[table_size];
|
PerfVariable* _perf_sizes[table_size];
|
||||||
|
|
|
@ -188,7 +188,7 @@ class GCAdaptivePolicyCounters : public GCPolicyCounters {
|
||||||
inline void update_survivor_overflowed(bool survivor_overflowed) {
|
inline void update_survivor_overflowed(bool survivor_overflowed) {
|
||||||
_survivor_overflowed_counter->set_value(survivor_overflowed);
|
_survivor_overflowed_counter->set_value(survivor_overflowed);
|
||||||
}
|
}
|
||||||
inline void update_tenuring_threshold(int threshold) {
|
inline void update_tenuring_threshold(uint threshold) {
|
||||||
tenuring_threshold()->set_value(threshold);
|
tenuring_threshold()->set_value(threshold);
|
||||||
}
|
}
|
||||||
inline void update_increment_tenuring_threshold_for_gc_cost() {
|
inline void update_increment_tenuring_threshold_for_gc_cost() {
|
||||||
|
|
|
@ -87,7 +87,7 @@ void ParGCAllocBuffer::flush_stats(PLABStats* stats) {
|
||||||
// Compute desired plab size and latch result for later
|
// Compute desired plab size and latch result for later
|
||||||
// use. This should be called once at the end of parallel
|
// use. This should be called once at the end of parallel
|
||||||
// scavenge; it clears the sensor accumulators.
|
// scavenge; it clears the sensor accumulators.
|
||||||
void PLABStats::adjust_desired_plab_sz() {
|
void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) {
|
||||||
assert(ResizePLAB, "Not set");
|
assert(ResizePLAB, "Not set");
|
||||||
if (_allocated == 0) {
|
if (_allocated == 0) {
|
||||||
assert(_unused == 0,
|
assert(_unused == 0,
|
||||||
|
@ -107,7 +107,7 @@ void PLABStats::adjust_desired_plab_sz() {
|
||||||
target_refills = 1;
|
target_refills = 1;
|
||||||
}
|
}
|
||||||
_used = _allocated - _wasted - _unused;
|
_used = _allocated - _wasted - _unused;
|
||||||
size_t plab_sz = _used/(target_refills*ParallelGCThreads);
|
size_t plab_sz = _used/(target_refills*no_of_gc_workers);
|
||||||
if (PrintPLAB) gclog_or_tty->print(" (plab_sz = %d ", plab_sz);
|
if (PrintPLAB) gclog_or_tty->print(" (plab_sz = %d ", plab_sz);
|
||||||
// Take historical weighted average
|
// Take historical weighted average
|
||||||
_filter.sample(plab_sz);
|
_filter.sample(plab_sz);
|
||||||
|
|
|
@ -204,7 +204,8 @@ class PLABStats VALUE_OBJ_CLASS_SPEC {
|
||||||
return _desired_plab_sz;
|
return _desired_plab_sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjust_desired_plab_sz(); // filter computation, latches output to
|
void adjust_desired_plab_sz(uint no_of_gc_workers);
|
||||||
|
// filter computation, latches output to
|
||||||
// _desired_plab_sz, clears sensor accumulators
|
// _desired_plab_sz, clears sensor accumulators
|
||||||
|
|
||||||
void add_allocated(size_t v) {
|
void add_allocated(size_t v) {
|
||||||
|
|
|
@ -198,8 +198,6 @@ void VM_CollectForMetadataAllocation::doit() {
|
||||||
CollectedHeap* heap = Universe::heap();
|
CollectedHeap* heap = Universe::heap();
|
||||||
GCCauseSetter gccs(heap, _gc_cause);
|
GCCauseSetter gccs(heap, _gc_cause);
|
||||||
|
|
||||||
bool do_cms_concurrent = false;
|
|
||||||
|
|
||||||
// Check again if the space is available. Another thread
|
// Check again if the space is available. Another thread
|
||||||
// may have similarly failed a metadata allocation and induced
|
// may have similarly failed a metadata allocation and induced
|
||||||
// a GC that freed space for the allocation.
|
// a GC that freed space for the allocation.
|
||||||
|
@ -208,23 +206,25 @@ void VM_CollectForMetadataAllocation::doit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_result == NULL) {
|
if (_result == NULL) {
|
||||||
if (!UseConcMarkSweepGC) {
|
if (UseConcMarkSweepGC) {
|
||||||
// Don't clear the soft refs the first time.
|
if (CMSClassUnloadingEnabled) {
|
||||||
heap->collect_as_vm_thread(GCCause::_metadata_GC_threshold);
|
MetaspaceGC::set_should_concurrent_collect(true);
|
||||||
_result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
|
}
|
||||||
// Don't do this for now
|
// For CMS expand since the collection is going to be concurrent.
|
||||||
// This seems too costly to do a second full GC
|
_result =
|
||||||
// Let the metaspace grow instead
|
_loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype);
|
||||||
// if (_result == NULL) {
|
|
||||||
// // If allocation fails again, clear soft refs
|
|
||||||
// heap->collect_as_vm_thread(GCCause::_last_ditch_collection);
|
|
||||||
// _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
|
|
||||||
// }
|
|
||||||
} else {
|
|
||||||
MetaspaceGC::set_should_concurrent_collect(true);
|
|
||||||
do_cms_concurrent = true;
|
|
||||||
}
|
}
|
||||||
if (_result == NULL) {
|
if (_result == NULL) {
|
||||||
|
// Don't clear the soft refs. This GC is for reclaiming metadata
|
||||||
|
// and is unrelated to the fullness of the Java heap which should
|
||||||
|
// be the criteria for clearing SoftReferences.
|
||||||
|
if (Verbose && PrintGCDetails && UseConcMarkSweepGC) {
|
||||||
|
gclog_or_tty->print_cr("\nCMS full GC for Metaspace");
|
||||||
|
}
|
||||||
|
heap->collect_as_vm_thread(GCCause::_metadata_GC_threshold);
|
||||||
|
_result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
|
||||||
|
}
|
||||||
|
if (_result == NULL && !UseConcMarkSweepGC /* CMS already tried */) {
|
||||||
// If still failing, allow the Metaspace to expand.
|
// If still failing, allow the Metaspace to expand.
|
||||||
// See delta_capacity_until_GC() for explanation of the
|
// See delta_capacity_until_GC() for explanation of the
|
||||||
// amount of the expansion.
|
// amount of the expansion.
|
||||||
|
@ -233,18 +233,10 @@ void VM_CollectForMetadataAllocation::doit() {
|
||||||
_result =
|
_result =
|
||||||
_loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype);
|
_loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype);
|
||||||
|
|
||||||
if (do_cms_concurrent && _result == NULL) {
|
}
|
||||||
// Rather than fail with a metaspace out-of-memory, do a full
|
if (Verbose && PrintGCDetails && _result == NULL) {
|
||||||
// GC for CMS.
|
gclog_or_tty->print_cr("\nAfter Metaspace GC failed to allocate size "
|
||||||
heap->collect_as_vm_thread(GCCause::_metadata_GC_threshold);
|
SIZE_FORMAT, _size);
|
||||||
_result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
|
|
||||||
}
|
|
||||||
if (_result == NULL) {
|
|
||||||
if (PrintGCDetails) {
|
|
||||||
gclog_or_tty->print_cr("\nAfter Metaspace GC failed to allocate size "
|
|
||||||
SIZE_FORMAT, _size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -737,6 +737,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invokehandle(JavaThread* thread)) {
|
||||||
pool,
|
pool,
|
||||||
info.resolved_method(),
|
info.resolved_method(),
|
||||||
info.resolved_appendix(),
|
info.resolved_appendix(),
|
||||||
|
info.resolved_method_type(),
|
||||||
pool->resolved_references());
|
pool->resolved_references());
|
||||||
}
|
}
|
||||||
IRT_END
|
IRT_END
|
||||||
|
@ -765,6 +766,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
|
||||||
pool,
|
pool,
|
||||||
info.resolved_method(),
|
info.resolved_method(),
|
||||||
info.resolved_appendix(),
|
info.resolved_appendix(),
|
||||||
|
info.resolved_method_type(),
|
||||||
pool->resolved_references());
|
pool->resolved_references());
|
||||||
}
|
}
|
||||||
IRT_END
|
IRT_END
|
||||||
|
|
|
@ -99,7 +99,7 @@ void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klas
|
||||||
assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call");
|
assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix, TRAPS) {
|
void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS) {
|
||||||
if (resolved_method.is_null()) {
|
if (resolved_method.is_null()) {
|
||||||
THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null");
|
THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null");
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,8 @@ void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix
|
||||||
int vtable_index = Method::nonvirtual_vtable_index;
|
int vtable_index = Method::nonvirtual_vtable_index;
|
||||||
assert(resolved_method->vtable_index() == vtable_index, "");
|
assert(resolved_method->vtable_index() == vtable_index, "");
|
||||||
set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
|
set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
|
||||||
_resolved_appendix = resolved_appendix;
|
_resolved_appendix = resolved_appendix;
|
||||||
|
_resolved_method_type = resolved_method_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
|
void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
|
||||||
|
@ -221,7 +222,8 @@ void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle
|
||||||
void LinkResolver::lookup_polymorphic_method(methodHandle& result,
|
void LinkResolver::lookup_polymorphic_method(methodHandle& result,
|
||||||
KlassHandle klass, Symbol* name, Symbol* full_signature,
|
KlassHandle klass, Symbol* name, Symbol* full_signature,
|
||||||
KlassHandle current_klass,
|
KlassHandle current_klass,
|
||||||
Handle* appendix_result_or_null,
|
Handle *appendix_result_or_null,
|
||||||
|
Handle *method_type_result,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name);
|
vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name);
|
||||||
if (TraceMethodHandles) {
|
if (TraceMethodHandles) {
|
||||||
|
@ -275,10 +277,12 @@ void LinkResolver::lookup_polymorphic_method(methodHandle& result,
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle appendix;
|
Handle appendix;
|
||||||
|
Handle method_type;
|
||||||
result = SystemDictionary::find_method_handle_invoker(name,
|
result = SystemDictionary::find_method_handle_invoker(name,
|
||||||
full_signature,
|
full_signature,
|
||||||
current_klass,
|
current_klass,
|
||||||
&appendix,
|
&appendix,
|
||||||
|
&method_type,
|
||||||
CHECK);
|
CHECK);
|
||||||
if (TraceMethodHandles) {
|
if (TraceMethodHandles) {
|
||||||
tty->print("lookup_polymorphic_method => (via Java) ");
|
tty->print("lookup_polymorphic_method => (via Java) ");
|
||||||
|
@ -307,6 +311,7 @@ void LinkResolver::lookup_polymorphic_method(methodHandle& result,
|
||||||
|
|
||||||
assert(appendix_result_or_null != NULL, "");
|
assert(appendix_result_or_null != NULL, "");
|
||||||
(*appendix_result_or_null) = appendix;
|
(*appendix_result_or_null) = appendix;
|
||||||
|
(*method_type_result) = method_type;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,7 +424,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
|
||||||
if (resolved_method.is_null()) {
|
if (resolved_method.is_null()) {
|
||||||
// JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
|
// JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
|
||||||
lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
|
lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
|
||||||
current_klass, (Handle*)NULL, THREAD);
|
current_klass, (Handle*)NULL, (Handle*)NULL, THREAD);
|
||||||
if (HAS_PENDING_EXCEPTION) {
|
if (HAS_PENDING_EXCEPTION) {
|
||||||
nested_exception = Handle(THREAD, PENDING_EXCEPTION);
|
nested_exception = Handle(THREAD, PENDING_EXCEPTION);
|
||||||
CLEAR_PENDING_EXCEPTION;
|
CLEAR_PENDING_EXCEPTION;
|
||||||
|
@ -1207,11 +1212,12 @@ void LinkResolver::resolve_handle_call(CallInfo& result, KlassHandle resolved_kl
|
||||||
assert(resolved_klass() == SystemDictionary::MethodHandle_klass(), "");
|
assert(resolved_klass() == SystemDictionary::MethodHandle_klass(), "");
|
||||||
assert(MethodHandles::is_signature_polymorphic_name(method_name), "");
|
assert(MethodHandles::is_signature_polymorphic_name(method_name), "");
|
||||||
methodHandle resolved_method;
|
methodHandle resolved_method;
|
||||||
Handle resolved_appendix;
|
Handle resolved_appendix;
|
||||||
|
Handle resolved_method_type;
|
||||||
lookup_polymorphic_method(resolved_method, resolved_klass,
|
lookup_polymorphic_method(resolved_method, resolved_klass,
|
||||||
method_name, method_signature,
|
method_name, method_signature,
|
||||||
current_klass, &resolved_appendix, CHECK);
|
current_klass, &resolved_appendix, &resolved_method_type, CHECK);
|
||||||
result.set_handle(resolved_method, resolved_appendix, CHECK);
|
result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1219,7 +1225,7 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po
|
||||||
assert(EnableInvokeDynamic, "");
|
assert(EnableInvokeDynamic, "");
|
||||||
pool->set_invokedynamic(); // mark header to flag active call sites
|
pool->set_invokedynamic(); // mark header to flag active call sites
|
||||||
|
|
||||||
//resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK);
|
//resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK);
|
||||||
Symbol* method_name = pool->name_ref_at(index);
|
Symbol* method_name = pool->name_ref_at(index);
|
||||||
Symbol* method_signature = pool->signature_ref_at(index);
|
Symbol* method_signature = pool->signature_ref_at(index);
|
||||||
KlassHandle current_klass = KlassHandle(THREAD, pool->pool_holder());
|
KlassHandle current_klass = KlassHandle(THREAD, pool->pool_holder());
|
||||||
|
@ -1236,9 +1242,10 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po
|
||||||
bootstrap_specifier = Handle(THREAD, bsm_info);
|
bootstrap_specifier = Handle(THREAD, bsm_info);
|
||||||
}
|
}
|
||||||
if (!cpce->is_f1_null()) {
|
if (!cpce->is_f1_null()) {
|
||||||
methodHandle method(THREAD, cpce->f1_as_method());
|
methodHandle method( THREAD, cpce->f1_as_method());
|
||||||
Handle appendix(THREAD, cpce->appendix_if_resolved(pool));
|
Handle appendix( THREAD, cpce->appendix_if_resolved(pool));
|
||||||
result.set_handle(method, appendix, CHECK);
|
Handle method_type(THREAD, cpce->method_type_if_resolved(pool));
|
||||||
|
result.set_handle(method, appendix, method_type, CHECK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1260,11 +1267,13 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
|
||||||
// JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...)
|
// JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...)
|
||||||
// The appendix argument is likely to be a freshly-created CallSite.
|
// The appendix argument is likely to be a freshly-created CallSite.
|
||||||
Handle resolved_appendix;
|
Handle resolved_appendix;
|
||||||
|
Handle resolved_method_type;
|
||||||
methodHandle resolved_method =
|
methodHandle resolved_method =
|
||||||
SystemDictionary::find_dynamic_call_site_invoker(current_klass,
|
SystemDictionary::find_dynamic_call_site_invoker(current_klass,
|
||||||
bootstrap_specifier,
|
bootstrap_specifier,
|
||||||
method_name, method_signature,
|
method_name, method_signature,
|
||||||
&resolved_appendix,
|
&resolved_appendix,
|
||||||
|
&resolved_method_type,
|
||||||
THREAD);
|
THREAD);
|
||||||
if (HAS_PENDING_EXCEPTION) {
|
if (HAS_PENDING_EXCEPTION) {
|
||||||
if (TraceMethodHandles) {
|
if (TraceMethodHandles) {
|
||||||
|
@ -1284,7 +1293,7 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
|
||||||
CLEAR_PENDING_EXCEPTION;
|
CLEAR_PENDING_EXCEPTION;
|
||||||
THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception)
|
THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception)
|
||||||
}
|
}
|
||||||
result.set_handle(resolved_method, resolved_appendix, CHECK);
|
result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -76,12 +76,13 @@ class CallInfo: public LinkInfo {
|
||||||
methodHandle _selected_method; // dynamic (actual) target method
|
methodHandle _selected_method; // dynamic (actual) target method
|
||||||
int _vtable_index; // vtable index of selected method
|
int _vtable_index; // vtable index of selected method
|
||||||
Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix)
|
Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix)
|
||||||
|
Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites)
|
||||||
|
|
||||||
void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS);
|
void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS);
|
||||||
void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method , TRAPS);
|
void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method , TRAPS);
|
||||||
void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS);
|
void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS);
|
||||||
void set_handle( methodHandle resolved_method, Handle resolved_appendix, TRAPS);
|
void set_handle( methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS);
|
||||||
void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS);
|
void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS);
|
||||||
|
|
||||||
friend class LinkResolver;
|
friend class LinkResolver;
|
||||||
|
|
||||||
|
@ -91,6 +92,7 @@ class CallInfo: public LinkInfo {
|
||||||
methodHandle resolved_method() const { return _resolved_method; }
|
methodHandle resolved_method() const { return _resolved_method; }
|
||||||
methodHandle selected_method() const { return _selected_method; }
|
methodHandle selected_method() const { return _selected_method; }
|
||||||
Handle resolved_appendix() const { return _resolved_appendix; }
|
Handle resolved_appendix() const { return _resolved_appendix; }
|
||||||
|
Handle resolved_method_type() const { return _resolved_method_type; }
|
||||||
|
|
||||||
BasicType result_type() const { return selected_method()->result_type(); }
|
BasicType result_type() const { return selected_method()->result_type(); }
|
||||||
bool has_vtable_index() const { return _vtable_index >= 0; }
|
bool has_vtable_index() const { return _vtable_index >= 0; }
|
||||||
|
@ -113,7 +115,7 @@ class LinkResolver: AllStatic {
|
||||||
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||||
static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||||
static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
|
static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
|
||||||
KlassHandle current_klass, Handle* appendix_result_or_null, TRAPS);
|
KlassHandle current_klass, Handle *appendix_result_or_null, Handle *method_type_result, TRAPS);
|
||||||
|
|
||||||
static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_i
|
||||||
MethodHandles::is_signature_polymorphic_name(SystemDictionary::MethodHandle_klass(),
|
MethodHandles::is_signature_polymorphic_name(SystemDictionary::MethodHandle_klass(),
|
||||||
_pool->name_ref_at(cp_index))) {
|
_pool->name_ref_at(cp_index))) {
|
||||||
// we may need a resolved_refs entry for the appendix
|
// we may need a resolved_refs entry for the appendix
|
||||||
add_invokedynamic_resolved_references_entry(cp_index, cache_index);
|
add_invokedynamic_resolved_references_entries(cp_index, cache_index);
|
||||||
status = +1;
|
status = +1;
|
||||||
} else {
|
} else {
|
||||||
status = -1;
|
status = -1;
|
||||||
|
@ -211,7 +211,7 @@ void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) {
|
||||||
if (!reverse) {
|
if (!reverse) {
|
||||||
int cp_index = Bytes::get_Java_u2(p);
|
int cp_index = Bytes::get_Java_u2(p);
|
||||||
int cache_index = add_invokedynamic_cp_cache_entry(cp_index);
|
int cache_index = add_invokedynamic_cp_cache_entry(cp_index);
|
||||||
add_invokedynamic_resolved_references_entry(cp_index, cache_index);
|
add_invokedynamic_resolved_references_entries(cp_index, cache_index);
|
||||||
// Replace the trailing four bytes with a CPC index for the dynamic
|
// Replace the trailing four bytes with a CPC index for the dynamic
|
||||||
// call site. Unlike other CPC entries, there is one per bytecode,
|
// call site. Unlike other CPC entries, there is one per bytecode,
|
||||||
// not just one per distinct CP entry. In other words, the
|
// not just one per distinct CP entry. In other words, the
|
||||||
|
|
|
@ -113,12 +113,19 @@ class Rewriter: public StackObj {
|
||||||
return ref_index;
|
return ref_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a new entry to the resolved_references map (for invokedynamic only)
|
// add a new entries to the resolved_references map (for invokedynamic and invokehandle only)
|
||||||
int add_invokedynamic_resolved_references_entry(int cp_index, int cache_index) {
|
int add_invokedynamic_resolved_references_entries(int cp_index, int cache_index) {
|
||||||
assert(_resolved_reference_limit >= 0, "must add indy refs after first iteration");
|
assert(_resolved_reference_limit >= 0, "must add indy refs after first iteration");
|
||||||
int ref_index = _resolved_references_map.append(cp_index); // many-to-one
|
int ref_index = -1;
|
||||||
assert(ref_index >= _resolved_reference_limit, "");
|
for (int entry = 0; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
|
||||||
_invokedynamic_references_map.at_put_grow(ref_index, cache_index, -1);
|
const int index = _resolved_references_map.append(cp_index); // many-to-one
|
||||||
|
assert(index >= _resolved_reference_limit, "");
|
||||||
|
if (entry == 0) {
|
||||||
|
ref_index = index;
|
||||||
|
}
|
||||||
|
assert((index - entry) == ref_index, "entries must be consecutive");
|
||||||
|
_invokedynamic_references_map.at_put_grow(index, cache_index, -1);
|
||||||
|
}
|
||||||
return ref_index;
|
return ref_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,15 +134,6 @@ class Rewriter: public StackObj {
|
||||||
return cp_index;
|
return cp_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// invokedynamic support - append the cpCache entry (encoded) in object map.
|
|
||||||
// The resolved_references_map should still be in ascending order
|
|
||||||
// The resolved_references has the invokedynamic call site objects appended after
|
|
||||||
// the objects that are resolved in the constant pool.
|
|
||||||
int add_callsite_entry(int main_cpc_entry) {
|
|
||||||
int ref_index = _resolved_references_map.append(main_cpc_entry);
|
|
||||||
return ref_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Access the contents of _cp_cache_map to determine CP cache layout.
|
// Access the contents of _cp_cache_map to determine CP cache layout.
|
||||||
int cp_cache_entry_pool_index(int cache_index) {
|
int cp_cache_entry_pool_index(int cache_index) {
|
||||||
int cp_index = _cp_cache_map[cache_index];
|
int cp_index = _cp_cache_map[cache_index];
|
||||||
|
|
|
@ -43,7 +43,7 @@ class DefNewGeneration: public Generation {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Generation* _next_gen;
|
Generation* _next_gen;
|
||||||
int _tenuring_threshold; // Tenuring threshold for next collection.
|
uint _tenuring_threshold; // Tenuring threshold for next collection.
|
||||||
ageTable _age_table;
|
ageTable _age_table;
|
||||||
// Size of object to pretenure in words; command line provides bytes
|
// Size of object to pretenure in words; command line provides bytes
|
||||||
size_t _pretenure_size_threshold_words;
|
size_t _pretenure_size_threshold_words;
|
||||||
|
@ -325,7 +325,7 @@ protected:
|
||||||
bool parallel = false);
|
bool parallel = false);
|
||||||
|
|
||||||
oop copy_to_survivor_space(oop old);
|
oop copy_to_survivor_space(oop old);
|
||||||
int tenuring_threshold() { return _tenuring_threshold; }
|
uint tenuring_threshold() { return _tenuring_threshold; }
|
||||||
|
|
||||||
// Performance Counter support
|
// Performance Counter support
|
||||||
void update_counters();
|
void update_counters();
|
||||||
|
|
|
@ -35,7 +35,7 @@ class GlobalTLABStats;
|
||||||
// the threads for allocation.
|
// the threads for allocation.
|
||||||
// It is thread-private at any time, but maybe multiplexed over
|
// It is thread-private at any time, but maybe multiplexed over
|
||||||
// time across multiple threads. The park()/unpark() pair is
|
// time across multiple threads. The park()/unpark() pair is
|
||||||
// used to make it avaiable for such multiplexing.
|
// used to make it available for such multiplexing.
|
||||||
class ThreadLocalAllocBuffer: public CHeapObj<mtThread> {
|
class ThreadLocalAllocBuffer: public CHeapObj<mtThread> {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -445,7 +445,6 @@ bool ConstantPool::has_appendix_at_if_loaded(constantPoolHandle cpool, int which
|
||||||
return e->has_appendix();
|
return e->has_appendix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
oop ConstantPool::appendix_at_if_loaded(constantPoolHandle cpool, int which) {
|
oop ConstantPool::appendix_at_if_loaded(constantPoolHandle cpool, int which) {
|
||||||
if (cpool->cache() == NULL) return NULL; // nothing to load yet
|
if (cpool->cache() == NULL) return NULL; // nothing to load yet
|
||||||
int cache_index = decode_cpcache_index(which, true);
|
int cache_index = decode_cpcache_index(which, true);
|
||||||
|
@ -454,6 +453,21 @@ oop ConstantPool::appendix_at_if_loaded(constantPoolHandle cpool, int which) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ConstantPool::has_method_type_at_if_loaded(constantPoolHandle cpool, int which) {
|
||||||
|
if (cpool->cache() == NULL) return false; // nothing to load yet
|
||||||
|
int cache_index = decode_cpcache_index(which, true);
|
||||||
|
ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
|
||||||
|
return e->has_method_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
oop ConstantPool::method_type_at_if_loaded(constantPoolHandle cpool, int which) {
|
||||||
|
if (cpool->cache() == NULL) return NULL; // nothing to load yet
|
||||||
|
int cache_index = decode_cpcache_index(which, true);
|
||||||
|
ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
|
||||||
|
return e->method_type_if_resolved(cpool);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Symbol* ConstantPool::impl_name_ref_at(int which, bool uncached) {
|
Symbol* ConstantPool::impl_name_ref_at(int which, bool uncached) {
|
||||||
int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached));
|
int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached));
|
||||||
return symbol_at(name_index);
|
return symbol_at(name_index);
|
||||||
|
|
|
@ -694,13 +694,15 @@ class ConstantPool : public Metadata {
|
||||||
friend class SystemDictionary;
|
friend class SystemDictionary;
|
||||||
|
|
||||||
// Used by compiler to prevent classloading.
|
// Used by compiler to prevent classloading.
|
||||||
static Method* method_at_if_loaded (constantPoolHandle this_oop, int which);
|
static Method* method_at_if_loaded (constantPoolHandle this_oop, int which);
|
||||||
static bool has_appendix_at_if_loaded (constantPoolHandle this_oop, int which);
|
static bool has_appendix_at_if_loaded (constantPoolHandle this_oop, int which);
|
||||||
static oop appendix_at_if_loaded (constantPoolHandle this_oop, int which);
|
static oop appendix_at_if_loaded (constantPoolHandle this_oop, int which);
|
||||||
static Klass* klass_at_if_loaded (constantPoolHandle this_oop, int which);
|
static bool has_method_type_at_if_loaded (constantPoolHandle this_oop, int which);
|
||||||
static Klass* klass_ref_at_if_loaded (constantPoolHandle this_oop, int which);
|
static oop method_type_at_if_loaded (constantPoolHandle this_oop, int which);
|
||||||
|
static Klass* klass_at_if_loaded (constantPoolHandle this_oop, int which);
|
||||||
|
static Klass* klass_ref_at_if_loaded (constantPoolHandle this_oop, int which);
|
||||||
// Same as above - but does LinkResolving.
|
// Same as above - but does LinkResolving.
|
||||||
static Klass* klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int which, TRAPS);
|
static Klass* klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int which, TRAPS);
|
||||||
|
|
||||||
// Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
|
// Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
|
||||||
// future by other Java code. These take constant pool indices rather than
|
// future by other Java code. These take constant pool indices rather than
|
||||||
|
|
|
@ -244,21 +244,23 @@ void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index)
|
||||||
|
|
||||||
|
|
||||||
void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool,
|
void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool,
|
||||||
methodHandle adapter, Handle appendix,
|
methodHandle adapter,
|
||||||
|
Handle appendix, Handle method_type,
|
||||||
objArrayHandle resolved_references) {
|
objArrayHandle resolved_references) {
|
||||||
set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, resolved_references);
|
set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, method_type, resolved_references);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool,
|
void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool,
|
||||||
methodHandle adapter, Handle appendix,
|
methodHandle adapter,
|
||||||
|
Handle appendix, Handle method_type,
|
||||||
objArrayHandle resolved_references) {
|
objArrayHandle resolved_references) {
|
||||||
set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, resolved_references);
|
set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, method_type, resolved_references);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
|
void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
|
||||||
Bytecodes::Code invoke_code,
|
Bytecodes::Code invoke_code,
|
||||||
methodHandle adapter,
|
methodHandle adapter,
|
||||||
Handle appendix,
|
Handle appendix, Handle method_type,
|
||||||
objArrayHandle resolved_references) {
|
objArrayHandle resolved_references) {
|
||||||
// NOTE: This CPCE can be the subject of data races.
|
// NOTE: This CPCE can be the subject of data races.
|
||||||
// There are three words to update: flags, refs[f2], f1 (in that order).
|
// There are three words to update: flags, refs[f2], f1 (in that order).
|
||||||
|
@ -274,18 +276,21 @@ void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_appendix = appendix.not_null();
|
const bool has_appendix = appendix.not_null();
|
||||||
|
const bool has_method_type = method_type.not_null();
|
||||||
|
|
||||||
// Write the flags.
|
// Write the flags.
|
||||||
set_method_flags(as_TosState(adapter->result_type()),
|
set_method_flags(as_TosState(adapter->result_type()),
|
||||||
((has_appendix ? 1 : 0) << has_appendix_shift) |
|
((has_appendix ? 1 : 0) << has_appendix_shift ) |
|
||||||
( 1 << is_final_shift),
|
((has_method_type ? 1 : 0) << has_method_type_shift) |
|
||||||
|
( 1 << is_final_shift ),
|
||||||
adapter->size_of_parameters());
|
adapter->size_of_parameters());
|
||||||
|
|
||||||
if (TraceInvokeDynamic) {
|
if (TraceInvokeDynamic) {
|
||||||
tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method="PTR_FORMAT" ",
|
tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
|
||||||
invoke_code,
|
invoke_code,
|
||||||
(intptr_t)appendix(), (has_appendix ? "" : " (unused)"),
|
(intptr_t)appendix(), (has_appendix ? "" : " (unused)"),
|
||||||
|
(intptr_t)method_type(), (has_method_type ? "" : " (unused)"),
|
||||||
(intptr_t)adapter());
|
(intptr_t)adapter());
|
||||||
adapter->print();
|
adapter->print();
|
||||||
if (has_appendix) appendix()->print();
|
if (has_appendix) appendix()->print();
|
||||||
|
@ -310,17 +315,26 @@ void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
|
||||||
// This allows us to create fewer method oops, while keeping type safety.
|
// This allows us to create fewer method oops, while keeping type safety.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// Store appendix, if any.
|
||||||
if (has_appendix) {
|
if (has_appendix) {
|
||||||
int ref_index = f2_as_index();
|
const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
|
||||||
assert(ref_index >= 0 && ref_index < resolved_references->length(), "oob");
|
assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
|
||||||
assert(resolved_references->obj_at(ref_index) == NULL, "init just once");
|
assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
|
||||||
resolved_references->obj_at_put(ref_index, appendix());
|
resolved_references->obj_at_put(appendix_index, appendix());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store MethodType, if any.
|
||||||
|
if (has_method_type) {
|
||||||
|
const int method_type_index = f2_as_index() + _indy_resolved_references_method_type_offset;
|
||||||
|
assert(method_type_index >= 0 && method_type_index < resolved_references->length(), "oob");
|
||||||
|
assert(resolved_references->obj_at(method_type_index) == NULL, "init just once");
|
||||||
|
resolved_references->obj_at_put(method_type_index, method_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
release_set_f1(adapter()); // This must be the last one to set (see NOTE above)!
|
release_set_f1(adapter()); // This must be the last one to set (see NOTE above)!
|
||||||
|
|
||||||
// The interpreter assembly code does not check byte_2,
|
// The interpreter assembly code does not check byte_2,
|
||||||
// but it is used by is_resolved, method_if_resolved, etc.
|
// but it is used by is_resolved, method_if_resolved, etc.
|
||||||
set_bytecode_1(invoke_code);
|
set_bytecode_1(invoke_code);
|
||||||
NOT_PRODUCT(verify(tty));
|
NOT_PRODUCT(verify(tty));
|
||||||
if (TraceInvokeDynamic) {
|
if (TraceInvokeDynamic) {
|
||||||
|
@ -376,7 +390,16 @@ Method* ConstantPoolCacheEntry::method_if_resolved(constantPoolHandle cpool) {
|
||||||
oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) {
|
oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) {
|
||||||
if (is_f1_null() || !has_appendix())
|
if (is_f1_null() || !has_appendix())
|
||||||
return NULL;
|
return NULL;
|
||||||
int ref_index = f2_as_index();
|
const int ref_index = f2_as_index() + _indy_resolved_references_appendix_offset;
|
||||||
|
objArrayOop resolved_references = cpool->resolved_references();
|
||||||
|
return resolved_references->obj_at(ref_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) {
|
||||||
|
if (is_f1_null() || !has_method_type())
|
||||||
|
return NULL;
|
||||||
|
const int ref_index = f2_as_index() + _indy_resolved_references_method_type_offset;
|
||||||
objArrayOop resolved_references = cpool->resolved_references();
|
objArrayOop resolved_references = cpool->resolved_references();
|
||||||
return resolved_references->obj_at(ref_index);
|
return resolved_references->obj_at(ref_index);
|
||||||
}
|
}
|
||||||
|
@ -513,13 +536,23 @@ void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invoke
|
||||||
for (int i = 0; i < length(); i++) {
|
for (int i = 0; i < length(); i++) {
|
||||||
ConstantPoolCacheEntry* e = entry_at(i);
|
ConstantPoolCacheEntry* e = entry_at(i);
|
||||||
int original_index = inverse_index_map[i];
|
int original_index = inverse_index_map[i];
|
||||||
e->initialize_entry(original_index);
|
e->initialize_entry(original_index);
|
||||||
assert(entry_at(i) == e, "sanity");
|
assert(entry_at(i) == e, "sanity");
|
||||||
}
|
}
|
||||||
for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
|
for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
|
||||||
int cpci = invokedynamic_references_map[ref];
|
const int cpci = invokedynamic_references_map[ref];
|
||||||
if (cpci >= 0)
|
if (cpci >= 0) {
|
||||||
|
#ifdef ASSERT
|
||||||
|
// invokedynamic and invokehandle have more entries; check if they
|
||||||
|
// all point to the same constant pool cache entry.
|
||||||
|
for (int entry = 1; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
|
||||||
|
const int cpci_next = invokedynamic_references_map[ref + entry];
|
||||||
|
assert(cpci == cpci_next, err_msg_res("%d == %d", cpci, cpci_next));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
entry_at(cpci)->initialize_resolved_reference_index(ref);
|
entry_at(cpci)->initialize_resolved_reference_index(ref);
|
||||||
|
ref += ConstantPoolCacheEntry::_indy_resolved_references_entries - 1; // skip extra entries
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,10 +42,10 @@ class PSPromotionManager;
|
||||||
// _indices [ b2 | b1 | index ] index = constant_pool_index
|
// _indices [ b2 | b1 | index ] index = constant_pool_index
|
||||||
// _f1 [ entry specific ] metadata ptr (method or klass)
|
// _f1 [ entry specific ] metadata ptr (method or klass)
|
||||||
// _f2 [ entry specific ] vtable or res_ref index, or vfinal method ptr
|
// _f2 [ entry specific ] vtable or res_ref index, or vfinal method ptr
|
||||||
// _flags [tos|0|F=1|0|0|f|v|0 |00000|field_index] (for field entries)
|
// _flags [tos|0|F=1|0|0|0|f|v|0 |0000|field_index] (for field entries)
|
||||||
// bit length [ 4 |1| 1 |1|1|1|1|1 |--5--|----16-----]
|
// bit length [ 4 |1| 1 |1|1|1|1|1|1 |-4--|----16-----]
|
||||||
// _flags [tos|0|F=0|A|I|f|0|vf|00000|00000|psize] (for method entries)
|
// _flags [tos|0|F=0|M|A|I|f|0|vf|0000|00000|psize] (for method entries)
|
||||||
// bit length [ 4 |1| 1 |1|1|1|1|1 |--5--|--8--|--8--]
|
// bit length [ 4 |1| 1 |1|1|1|1|1|1 |-4--|--8--|--8--]
|
||||||
|
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
//
|
//
|
||||||
|
@ -166,11 +166,12 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
|
||||||
tos_state_shift = BitsPerInt - tos_state_bits, // see verify_tos_state_shift below
|
tos_state_shift = BitsPerInt - tos_state_bits, // see verify_tos_state_shift below
|
||||||
// misc. option bits; can be any bit position in [16..27]
|
// misc. option bits; can be any bit position in [16..27]
|
||||||
is_field_entry_shift = 26, // (F) is it a field or a method?
|
is_field_entry_shift = 26, // (F) is it a field or a method?
|
||||||
has_appendix_shift = 25, // (A) does the call site have an appendix argument?
|
has_method_type_shift = 25, // (M) does the call site have a MethodType?
|
||||||
is_forced_virtual_shift = 24, // (I) is the interface reference forced to virtual mode?
|
has_appendix_shift = 24, // (A) does the call site have an appendix argument?
|
||||||
is_final_shift = 23, // (f) is the field or method final?
|
is_forced_virtual_shift = 23, // (I) is the interface reference forced to virtual mode?
|
||||||
is_volatile_shift = 22, // (v) is the field volatile?
|
is_final_shift = 22, // (f) is the field or method final?
|
||||||
is_vfinal_shift = 21, // (vf) did the call resolve to a final method?
|
is_volatile_shift = 21, // (v) is the field volatile?
|
||||||
|
is_vfinal_shift = 20, // (vf) did the call resolve to a final method?
|
||||||
// low order bits give field index (for FieldInfo) or method parameter size:
|
// low order bits give field index (for FieldInfo) or method parameter size:
|
||||||
field_index_bits = 16,
|
field_index_bits = 16,
|
||||||
field_index_mask = right_n_bits(field_index_bits),
|
field_index_mask = right_n_bits(field_index_bits),
|
||||||
|
@ -223,14 +224,16 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
|
||||||
void set_method_handle(
|
void set_method_handle(
|
||||||
constantPoolHandle cpool, // holding constant pool (required for locking)
|
constantPoolHandle cpool, // holding constant pool (required for locking)
|
||||||
methodHandle method, // adapter for invokeExact, etc.
|
methodHandle method, // adapter for invokeExact, etc.
|
||||||
Handle appendix, // stored in refs[f2]; could be a java.lang.invoke.MethodType
|
Handle appendix, // stored in refs[f2+0]; could be a java.lang.invoke.MethodType
|
||||||
|
Handle method_type, // stored in refs[f2+1]; is a java.lang.invoke.MethodType
|
||||||
objArrayHandle resolved_references
|
objArrayHandle resolved_references
|
||||||
);
|
);
|
||||||
|
|
||||||
void set_dynamic_call(
|
void set_dynamic_call(
|
||||||
constantPoolHandle cpool, // holding constant pool (required for locking)
|
constantPoolHandle cpool, // holding constant pool (required for locking)
|
||||||
methodHandle method, // adapter for this call site
|
methodHandle method, // adapter for this call site
|
||||||
Handle appendix, // stored in refs[f2]; could be a java.lang.invoke.CallSite
|
Handle appendix, // stored in refs[f2+0]; could be a java.lang.invoke.CallSite
|
||||||
|
Handle method_type, // stored in refs[f2+1]; is a java.lang.invoke.MethodType
|
||||||
objArrayHandle resolved_references
|
objArrayHandle resolved_references
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -253,12 +256,24 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
|
||||||
constantPoolHandle cpool, // holding constant pool (required for locking)
|
constantPoolHandle cpool, // holding constant pool (required for locking)
|
||||||
Bytecodes::Code invoke_code, // _invokehandle or _invokedynamic
|
Bytecodes::Code invoke_code, // _invokehandle or _invokedynamic
|
||||||
methodHandle adapter, // invoker method (f1)
|
methodHandle adapter, // invoker method (f1)
|
||||||
Handle appendix, // appendix such as CallSite, MethodType, etc. (refs[f2])
|
Handle appendix, // appendix such as CallSite, MethodType, etc. (refs[f2+0])
|
||||||
|
Handle method_type, // MethodType (refs[f2+1])
|
||||||
objArrayHandle resolved_references
|
objArrayHandle resolved_references
|
||||||
);
|
);
|
||||||
|
|
||||||
Method* method_if_resolved(constantPoolHandle cpool);
|
// invokedynamic and invokehandle call sites have two entries in the
|
||||||
oop appendix_if_resolved(constantPoolHandle cpool);
|
// resolved references array:
|
||||||
|
// appendix (at index+0)
|
||||||
|
// MethodType (at index+1)
|
||||||
|
enum {
|
||||||
|
_indy_resolved_references_appendix_offset = 0,
|
||||||
|
_indy_resolved_references_method_type_offset = 1,
|
||||||
|
_indy_resolved_references_entries
|
||||||
|
};
|
||||||
|
|
||||||
|
Method* method_if_resolved(constantPoolHandle cpool);
|
||||||
|
oop appendix_if_resolved(constantPoolHandle cpool);
|
||||||
|
oop method_type_if_resolved(constantPoolHandle cpool);
|
||||||
|
|
||||||
void set_parameter_size(int value);
|
void set_parameter_size(int value);
|
||||||
|
|
||||||
|
@ -270,11 +285,11 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
|
||||||
case Bytecodes::_getfield : // fall through
|
case Bytecodes::_getfield : // fall through
|
||||||
case Bytecodes::_invokespecial : // fall through
|
case Bytecodes::_invokespecial : // fall through
|
||||||
case Bytecodes::_invokestatic : // fall through
|
case Bytecodes::_invokestatic : // fall through
|
||||||
|
case Bytecodes::_invokehandle : // fall through
|
||||||
|
case Bytecodes::_invokedynamic : // fall through
|
||||||
case Bytecodes::_invokeinterface : return 1;
|
case Bytecodes::_invokeinterface : return 1;
|
||||||
case Bytecodes::_putstatic : // fall through
|
case Bytecodes::_putstatic : // fall through
|
||||||
case Bytecodes::_putfield : // fall through
|
case Bytecodes::_putfield : // fall through
|
||||||
case Bytecodes::_invokehandle : // fall through
|
|
||||||
case Bytecodes::_invokedynamic : // fall through
|
|
||||||
case Bytecodes::_invokevirtual : return 2;
|
case Bytecodes::_invokevirtual : return 2;
|
||||||
default : break;
|
default : break;
|
||||||
}
|
}
|
||||||
|
@ -307,6 +322,7 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
|
||||||
bool is_forced_virtual() const { return (_flags & (1 << is_forced_virtual_shift)) != 0; }
|
bool is_forced_virtual() const { return (_flags & (1 << is_forced_virtual_shift)) != 0; }
|
||||||
bool is_vfinal() const { return (_flags & (1 << is_vfinal_shift)) != 0; }
|
bool is_vfinal() const { return (_flags & (1 << is_vfinal_shift)) != 0; }
|
||||||
bool has_appendix() const { return (_flags & (1 << has_appendix_shift)) != 0; }
|
bool has_appendix() const { return (_flags & (1 << has_appendix_shift)) != 0; }
|
||||||
|
bool has_method_type() const { return (_flags & (1 << has_method_type_shift)) != 0; }
|
||||||
bool is_method_entry() const { return (_flags & (1 << is_field_entry_shift)) == 0; }
|
bool is_method_entry() const { return (_flags & (1 << is_field_entry_shift)) == 0; }
|
||||||
bool is_field_entry() const { return (_flags & (1 << is_field_entry_shift)) != 0; }
|
bool is_field_entry() const { return (_flags & (1 << is_field_entry_shift)) != 0; }
|
||||||
bool is_byte() const { return flag_state() == btos; }
|
bool is_byte() const { return flag_state() == btos; }
|
||||||
|
|
|
@ -318,7 +318,7 @@ class markOopDesc: public oopDesc {
|
||||||
intptr_t tmp = (intptr_t) monitor;
|
intptr_t tmp = (intptr_t) monitor;
|
||||||
return (markOop) (tmp | monitor_value);
|
return (markOop) (tmp | monitor_value);
|
||||||
}
|
}
|
||||||
static markOop encode(JavaThread* thread, int age, int bias_epoch) {
|
static markOop encode(JavaThread* thread, uint age, int bias_epoch) {
|
||||||
intptr_t tmp = (intptr_t) thread;
|
intptr_t tmp = (intptr_t) thread;
|
||||||
assert(UseBiasedLocking && ((tmp & (epoch_mask_in_place | age_mask_in_place | biased_lock_mask_in_place)) == 0), "misaligned JavaThread pointer");
|
assert(UseBiasedLocking && ((tmp & (epoch_mask_in_place | age_mask_in_place | biased_lock_mask_in_place)) == 0), "misaligned JavaThread pointer");
|
||||||
assert(age <= max_age, "age too large");
|
assert(age <= max_age, "age too large");
|
||||||
|
@ -333,10 +333,10 @@ class markOopDesc: public oopDesc {
|
||||||
markOop set_marked() { return markOop((value() & ~lock_mask_in_place) | marked_value); }
|
markOop set_marked() { return markOop((value() & ~lock_mask_in_place) | marked_value); }
|
||||||
markOop set_unmarked() { return markOop((value() & ~lock_mask_in_place) | unlocked_value); }
|
markOop set_unmarked() { return markOop((value() & ~lock_mask_in_place) | unlocked_value); }
|
||||||
|
|
||||||
int age() const { return mask_bits(value() >> age_shift, age_mask); }
|
uint age() const { return mask_bits(value() >> age_shift, age_mask); }
|
||||||
markOop set_age(int v) const {
|
markOop set_age(uint v) const {
|
||||||
assert((v & ~age_mask) == 0, "shouldn't overflow age field");
|
assert((v & ~age_mask) == 0, "shouldn't overflow age field");
|
||||||
return markOop((value() & ~age_mask_in_place) | (((intptr_t)v & age_mask) << age_shift));
|
return markOop((value() & ~age_mask_in_place) | (((uintptr_t)v & age_mask) << age_shift));
|
||||||
}
|
}
|
||||||
markOop incr_age() const { return age() == max_age ? markOop(this) : set_age(age() + 1); }
|
markOop incr_age() const { return age() == max_age ? markOop(this) : set_age(age() + 1); }
|
||||||
|
|
||||||
|
|
|
@ -646,7 +646,7 @@ void objArrayKlass::oop_print_on(oop obj, outputStream* st) {
|
||||||
}
|
}
|
||||||
int remaining = oa->length() - print_len;
|
int remaining = oa->length() - print_len;
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
tty->print_cr(" - <%d more elements, increase MaxElementPrintSize to print>", remaining);
|
st->print_cr(" - <%d more elements, increase MaxElementPrintSize to print>", remaining);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -327,7 +327,7 @@ class oopDesc {
|
||||||
oop forwardee() const;
|
oop forwardee() const;
|
||||||
|
|
||||||
// Age of object during scavenge
|
// Age of object during scavenge
|
||||||
int age() const;
|
uint age() const;
|
||||||
void incr_age();
|
void incr_age();
|
||||||
|
|
||||||
// Adjust all pointers in this object to point at it's forwarded location and
|
// Adjust all pointers in this object to point at it's forwarded location and
|
||||||
|
|
|
@ -693,7 +693,7 @@ inline void oopDesc::set_displaced_mark(markOop m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following method needs to be MT safe.
|
// The following method needs to be MT safe.
|
||||||
inline int oopDesc::age() const {
|
inline uint oopDesc::age() const {
|
||||||
assert(!is_forwarded(), "Attempt to read age from forwarded mark");
|
assert(!is_forwarded(), "Attempt to read age from forwarded mark");
|
||||||
if (has_displaced_mark()) {
|
if (has_displaced_mark()) {
|
||||||
return displaced_mark()->age();
|
return displaced_mark()->age();
|
||||||
|
|
|
@ -381,7 +381,7 @@ void typeArrayKlass::oop_print_on(oop obj, outputStream* st) {
|
||||||
}
|
}
|
||||||
int remaining = ta->length() - print_len;
|
int remaining = ta->length() - print_len;
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
tty->print_cr(" - <%d more elements, increase MaxElementPrintSize to print>", remaining);
|
st->print_cr(" - <%d more elements, increase MaxElementPrintSize to print>", remaining);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -268,6 +268,8 @@ macro(MulVF)
|
||||||
macro(MulVD)
|
macro(MulVD)
|
||||||
macro(DivVF)
|
macro(DivVF)
|
||||||
macro(DivVD)
|
macro(DivVD)
|
||||||
|
macro(LShiftCntV)
|
||||||
|
macro(RShiftCntV)
|
||||||
macro(LShiftVB)
|
macro(LShiftVB)
|
||||||
macro(LShiftVS)
|
macro(LShiftVS)
|
||||||
macro(LShiftVI)
|
macro(LShiftVI)
|
||||||
|
|
|
@ -261,6 +261,7 @@ public:
|
||||||
|
|
||||||
// Vector ideal reg
|
// Vector ideal reg
|
||||||
static const int vector_ideal_reg(int len);
|
static const int vector_ideal_reg(int len);
|
||||||
|
static const int vector_shift_count_ideal_reg(int len);
|
||||||
|
|
||||||
// CPU supports misaligned vectors store/load.
|
// CPU supports misaligned vectors store/load.
|
||||||
static const bool misaligned_vectors_ok();
|
static const bool misaligned_vectors_ok();
|
||||||
|
|
|
@ -372,7 +372,8 @@ void Parse::load_interpreter_state(Node* osr_buf) {
|
||||||
// in the CFG, which typeflow had previously ignored.
|
// in the CFG, which typeflow had previously ignored.
|
||||||
// E.g., Object x = coldAtFirst() && notReached()? "str": new Integer(123).
|
// E.g., Object x = coldAtFirst() && notReached()? "str": new Integer(123).
|
||||||
// This x will be typed as Integer if notReached is not yet linked.
|
// This x will be typed as Integer if notReached is not yet linked.
|
||||||
uncommon_trap(Deoptimization::Reason_unreached,
|
// It could also happen due to a problem in ciTypeFlow analysis.
|
||||||
|
uncommon_trap(Deoptimization::Reason_constraint,
|
||||||
Deoptimization::Action_reinterpret);
|
Deoptimization::Action_reinterpret);
|
||||||
set_map(types_are_good);
|
set_map(types_are_good);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1436,10 +1436,9 @@ Node* SuperWord::vector_opd(Node_List* p, int opd_idx) {
|
||||||
return opd; // input is matching vector
|
return opd; // input is matching vector
|
||||||
}
|
}
|
||||||
if ((opd_idx == 2) && VectorNode::is_shift(p0)) {
|
if ((opd_idx == 2) && VectorNode::is_shift(p0)) {
|
||||||
// No vector is needed for shift count.
|
|
||||||
// Vector instructions do not mask shift count, do it here.
|
|
||||||
Compile* C = _phase->C;
|
Compile* C = _phase->C;
|
||||||
Node* cnt = opd;
|
Node* cnt = opd;
|
||||||
|
// Vector instructions do not mask shift count, do it here.
|
||||||
juint mask = (p0->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1);
|
juint mask = (p0->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1);
|
||||||
const TypeInt* t = opd->find_int_type();
|
const TypeInt* t = opd->find_int_type();
|
||||||
if (t != NULL && t->is_con()) {
|
if (t != NULL && t->is_con()) {
|
||||||
|
@ -1456,8 +1455,8 @@ Node* SuperWord::vector_opd(Node_List* p, int opd_idx) {
|
||||||
_phase->set_ctrl(cnt, _phase->get_ctrl(opd));
|
_phase->set_ctrl(cnt, _phase->get_ctrl(opd));
|
||||||
}
|
}
|
||||||
assert(opd->bottom_type()->isa_int(), "int type only");
|
assert(opd->bottom_type()->isa_int(), "int type only");
|
||||||
// Move non constant shift count into XMM register.
|
// Move non constant shift count into vector register.
|
||||||
cnt = new (C) MoveI2FNode(cnt);
|
cnt = VectorNode::shift_count(C, p0, cnt, vlen, velt_basic_type(p0));
|
||||||
}
|
}
|
||||||
if (cnt != opd) {
|
if (cnt != opd) {
|
||||||
_igvn.register_new_node_with_optimizer(cnt);
|
_igvn.register_new_node_with_optimizer(cnt);
|
||||||
|
|
|
@ -243,6 +243,8 @@ void VectorNode::vector_operands(Node* n, uint* start, uint* end) {
|
||||||
VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt) {
|
VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt) {
|
||||||
const TypeVect* vt = TypeVect::make(bt, vlen);
|
const TypeVect* vt = TypeVect::make(bt, vlen);
|
||||||
int vopc = VectorNode::opcode(opc, bt);
|
int vopc = VectorNode::opcode(opc, bt);
|
||||||
|
// This method should not be called for unimplemented vectors.
|
||||||
|
guarantee(vopc > 0, err_msg_res("Vector for '%s' is not implemented", NodeClassNames[opc]));
|
||||||
|
|
||||||
switch (vopc) {
|
switch (vopc) {
|
||||||
case Op_AddVB: return new (C) AddVBNode(n1, n2, vt);
|
case Op_AddVB: return new (C) AddVBNode(n1, n2, vt);
|
||||||
|
@ -286,7 +288,7 @@ VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen,
|
||||||
case Op_OrV: return new (C) OrVNode (n1, n2, vt);
|
case Op_OrV: return new (C) OrVNode (n1, n2, vt);
|
||||||
case Op_XorV: return new (C) XorVNode(n1, n2, vt);
|
case Op_XorV: return new (C) XorVNode(n1, n2, vt);
|
||||||
}
|
}
|
||||||
ShouldNotReachHere();
|
fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[vopc]));
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -312,7 +314,25 @@ VectorNode* VectorNode::scalar2vector(Compile* C, Node* s, uint vlen, const Type
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
return new (C) ReplicateDNode(s, vt);
|
return new (C) ReplicateDNode(s, vt);
|
||||||
}
|
}
|
||||||
ShouldNotReachHere();
|
fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorNode* VectorNode::shift_count(Compile* C, Node* shift, Node* cnt, uint vlen, BasicType bt) {
|
||||||
|
assert(VectorNode::is_shift(shift) && !cnt->is_Con(), "only variable shift count");
|
||||||
|
// Match shift count type with shift vector type.
|
||||||
|
const TypeVect* vt = TypeVect::make(bt, vlen);
|
||||||
|
switch (shift->Opcode()) {
|
||||||
|
case Op_LShiftI:
|
||||||
|
case Op_LShiftL:
|
||||||
|
return new (C) LShiftCntVNode(cnt, vt);
|
||||||
|
case Op_RShiftI:
|
||||||
|
case Op_RShiftL:
|
||||||
|
case Op_URShiftI:
|
||||||
|
case Op_URShiftL:
|
||||||
|
return new (C) RShiftCntVNode(cnt, vt);
|
||||||
|
}
|
||||||
|
fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +355,7 @@ PackNode* PackNode::make(Compile* C, Node* s, uint vlen, BasicType bt) {
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
return new (C) PackDNode(s, vt);
|
return new (C) PackDNode(s, vt);
|
||||||
}
|
}
|
||||||
ShouldNotReachHere();
|
fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +391,7 @@ PackNode* PackNode::binary_tree_pack(Compile* C, int lo, int hi) {
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
return new (C) Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
|
return new (C) Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
|
||||||
}
|
}
|
||||||
ShouldNotReachHere();
|
fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -381,7 +401,6 @@ LoadVectorNode* LoadVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem,
|
||||||
Node* adr, const TypePtr* atyp, uint vlen, BasicType bt) {
|
Node* adr, const TypePtr* atyp, uint vlen, BasicType bt) {
|
||||||
const TypeVect* vt = TypeVect::make(bt, vlen);
|
const TypeVect* vt = TypeVect::make(bt, vlen);
|
||||||
return new (C) LoadVectorNode(ctl, mem, adr, atyp, vt);
|
return new (C) LoadVectorNode(ctl, mem, adr, atyp, vt);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the vector version of a scalar store node.
|
// Return the vector version of a scalar store node.
|
||||||
|
@ -413,7 +432,7 @@ Node* ExtractNode::make(Compile* C, Node* v, uint position, BasicType bt) {
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
return new (C) ExtractDNode(v, pos);
|
return new (C) ExtractDNode(v, pos);
|
||||||
}
|
}
|
||||||
ShouldNotReachHere();
|
fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include "opto/node.hpp"
|
#include "opto/node.hpp"
|
||||||
#include "opto/opcodes.hpp"
|
#include "opto/opcodes.hpp"
|
||||||
|
|
||||||
//------------------------------VectorNode--------------------------------------
|
//------------------------------VectorNode-------------------------------------
|
||||||
// Vector Operation
|
// Vector Operation
|
||||||
class VectorNode : public TypeNode {
|
class VectorNode : public TypeNode {
|
||||||
public:
|
public:
|
||||||
|
@ -53,7 +53,7 @@ class VectorNode : public TypeNode {
|
||||||
virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
|
virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
|
||||||
|
|
||||||
static VectorNode* scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t);
|
static VectorNode* scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t);
|
||||||
|
static VectorNode* shift_count(Compile* C, Node* shift, Node* cnt, uint vlen, BasicType bt);
|
||||||
static VectorNode* make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
|
static VectorNode* make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
|
||||||
|
|
||||||
static int opcode(int opc, BasicType bt);
|
static int opcode(int opc, BasicType bt);
|
||||||
|
@ -64,9 +64,9 @@ class VectorNode : public TypeNode {
|
||||||
static void vector_operands(Node* n, uint* start, uint* end);
|
static void vector_operands(Node* n, uint* start, uint* end);
|
||||||
};
|
};
|
||||||
|
|
||||||
//===========================Vector=ALU=Operations====================================
|
//===========================Vector=ALU=Operations=============================
|
||||||
|
|
||||||
//------------------------------AddVBNode---------------------------------------
|
//------------------------------AddVBNode--------------------------------------
|
||||||
// Vector add byte
|
// Vector add byte
|
||||||
class AddVBNode : public VectorNode {
|
class AddVBNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -74,7 +74,7 @@ class AddVBNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------AddVSNode---------------------------------------
|
//------------------------------AddVSNode--------------------------------------
|
||||||
// Vector add char/short
|
// Vector add char/short
|
||||||
class AddVSNode : public VectorNode {
|
class AddVSNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -82,7 +82,7 @@ class AddVSNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------AddVINode---------------------------------------
|
//------------------------------AddVINode--------------------------------------
|
||||||
// Vector add int
|
// Vector add int
|
||||||
class AddVINode : public VectorNode {
|
class AddVINode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -90,7 +90,7 @@ class AddVINode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------AddVLNode---------------------------------------
|
//------------------------------AddVLNode--------------------------------------
|
||||||
// Vector add long
|
// Vector add long
|
||||||
class AddVLNode : public VectorNode {
|
class AddVLNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -98,7 +98,7 @@ class AddVLNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------AddVFNode---------------------------------------
|
//------------------------------AddVFNode--------------------------------------
|
||||||
// Vector add float
|
// Vector add float
|
||||||
class AddVFNode : public VectorNode {
|
class AddVFNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -106,7 +106,7 @@ class AddVFNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------AddVDNode---------------------------------------
|
//------------------------------AddVDNode--------------------------------------
|
||||||
// Vector add double
|
// Vector add double
|
||||||
class AddVDNode : public VectorNode {
|
class AddVDNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -114,7 +114,7 @@ class AddVDNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------SubVBNode---------------------------------------
|
//------------------------------SubVBNode--------------------------------------
|
||||||
// Vector subtract byte
|
// Vector subtract byte
|
||||||
class SubVBNode : public VectorNode {
|
class SubVBNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -122,7 +122,7 @@ class SubVBNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------SubVSNode---------------------------------------
|
//------------------------------SubVSNode--------------------------------------
|
||||||
// Vector subtract short
|
// Vector subtract short
|
||||||
class SubVSNode : public VectorNode {
|
class SubVSNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -130,7 +130,7 @@ class SubVSNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------SubVINode---------------------------------------
|
//------------------------------SubVINode--------------------------------------
|
||||||
// Vector subtract int
|
// Vector subtract int
|
||||||
class SubVINode : public VectorNode {
|
class SubVINode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -138,7 +138,7 @@ class SubVINode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------SubVLNode---------------------------------------
|
//------------------------------SubVLNode--------------------------------------
|
||||||
// Vector subtract long
|
// Vector subtract long
|
||||||
class SubVLNode : public VectorNode {
|
class SubVLNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -146,7 +146,7 @@ class SubVLNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------SubVFNode---------------------------------------
|
//------------------------------SubVFNode--------------------------------------
|
||||||
// Vector subtract float
|
// Vector subtract float
|
||||||
class SubVFNode : public VectorNode {
|
class SubVFNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -154,7 +154,7 @@ class SubVFNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------SubVDNode---------------------------------------
|
//------------------------------SubVDNode--------------------------------------
|
||||||
// Vector subtract double
|
// Vector subtract double
|
||||||
class SubVDNode : public VectorNode {
|
class SubVDNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -162,7 +162,7 @@ class SubVDNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------MulVSNode---------------------------------------
|
//------------------------------MulVSNode--------------------------------------
|
||||||
// Vector multiply short
|
// Vector multiply short
|
||||||
class MulVSNode : public VectorNode {
|
class MulVSNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -170,7 +170,7 @@ class MulVSNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------MulVINode---------------------------------------
|
//------------------------------MulVINode--------------------------------------
|
||||||
// Vector multiply int
|
// Vector multiply int
|
||||||
class MulVINode : public VectorNode {
|
class MulVINode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -178,7 +178,7 @@ class MulVINode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------MulVFNode---------------------------------------
|
//------------------------------MulVFNode--------------------------------------
|
||||||
// Vector multiply float
|
// Vector multiply float
|
||||||
class MulVFNode : public VectorNode {
|
class MulVFNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -186,7 +186,7 @@ class MulVFNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------MulVDNode---------------------------------------
|
//------------------------------MulVDNode--------------------------------------
|
||||||
// Vector multiply double
|
// Vector multiply double
|
||||||
class MulVDNode : public VectorNode {
|
class MulVDNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -194,7 +194,7 @@ class MulVDNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------DivVFNode---------------------------------------
|
//------------------------------DivVFNode--------------------------------------
|
||||||
// Vector divide float
|
// Vector divide float
|
||||||
class DivVFNode : public VectorNode {
|
class DivVFNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -202,7 +202,7 @@ class DivVFNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------DivVDNode---------------------------------------
|
//------------------------------DivVDNode--------------------------------------
|
||||||
// Vector Divide double
|
// Vector Divide double
|
||||||
class DivVDNode : public VectorNode {
|
class DivVDNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -210,7 +210,7 @@ class DivVDNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------LShiftVBNode---------------------------------------
|
//------------------------------LShiftVBNode-----------------------------------
|
||||||
// Vector left shift bytes
|
// Vector left shift bytes
|
||||||
class LShiftVBNode : public VectorNode {
|
class LShiftVBNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -218,7 +218,7 @@ class LShiftVBNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------LShiftVSNode---------------------------------------
|
//------------------------------LShiftVSNode-----------------------------------
|
||||||
// Vector left shift shorts
|
// Vector left shift shorts
|
||||||
class LShiftVSNode : public VectorNode {
|
class LShiftVSNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -226,7 +226,7 @@ class LShiftVSNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------LShiftVINode---------------------------------------
|
//------------------------------LShiftVINode-----------------------------------
|
||||||
// Vector left shift ints
|
// Vector left shift ints
|
||||||
class LShiftVINode : public VectorNode {
|
class LShiftVINode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -234,7 +234,7 @@ class LShiftVINode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------LShiftVLNode---------------------------------------
|
//------------------------------LShiftVLNode-----------------------------------
|
||||||
// Vector left shift longs
|
// Vector left shift longs
|
||||||
class LShiftVLNode : public VectorNode {
|
class LShiftVLNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -242,7 +242,7 @@ class LShiftVLNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------RShiftVBNode---------------------------------------
|
//------------------------------RShiftVBNode-----------------------------------
|
||||||
// Vector right arithmetic (signed) shift bytes
|
// Vector right arithmetic (signed) shift bytes
|
||||||
class RShiftVBNode : public VectorNode {
|
class RShiftVBNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -250,7 +250,7 @@ class RShiftVBNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------RShiftVSNode---------------------------------------
|
//------------------------------RShiftVSNode-----------------------------------
|
||||||
// Vector right arithmetic (signed) shift shorts
|
// Vector right arithmetic (signed) shift shorts
|
||||||
class RShiftVSNode : public VectorNode {
|
class RShiftVSNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -258,7 +258,7 @@ class RShiftVSNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------RShiftVINode---------------------------------------
|
//------------------------------RShiftVINode-----------------------------------
|
||||||
// Vector right arithmetic (signed) shift ints
|
// Vector right arithmetic (signed) shift ints
|
||||||
class RShiftVINode : public VectorNode {
|
class RShiftVINode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -266,7 +266,7 @@ class RShiftVINode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------RShiftVLNode---------------------------------------
|
//------------------------------RShiftVLNode-----------------------------------
|
||||||
// Vector right arithmetic (signed) shift longs
|
// Vector right arithmetic (signed) shift longs
|
||||||
class RShiftVLNode : public VectorNode {
|
class RShiftVLNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -274,7 +274,7 @@ class RShiftVLNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------URShiftVBNode---------------------------------------
|
//------------------------------URShiftVBNode----------------------------------
|
||||||
// Vector right logical (unsigned) shift bytes
|
// Vector right logical (unsigned) shift bytes
|
||||||
class URShiftVBNode : public VectorNode {
|
class URShiftVBNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -282,7 +282,7 @@ class URShiftVBNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------URShiftVSNode---------------------------------------
|
//------------------------------URShiftVSNode----------------------------------
|
||||||
// Vector right logical (unsigned) shift shorts
|
// Vector right logical (unsigned) shift shorts
|
||||||
class URShiftVSNode : public VectorNode {
|
class URShiftVSNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -290,7 +290,7 @@ class URShiftVSNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------URShiftVINode---------------------------------------
|
//------------------------------URShiftVINode----------------------------------
|
||||||
// Vector right logical (unsigned) shift ints
|
// Vector right logical (unsigned) shift ints
|
||||||
class URShiftVINode : public VectorNode {
|
class URShiftVINode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -298,7 +298,7 @@ class URShiftVINode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------URShiftVLNode---------------------------------------
|
//------------------------------URShiftVLNode----------------------------------
|
||||||
// Vector right logical (unsigned) shift longs
|
// Vector right logical (unsigned) shift longs
|
||||||
class URShiftVLNode : public VectorNode {
|
class URShiftVLNode : public VectorNode {
|
||||||
public:
|
public:
|
||||||
|
@ -306,6 +306,24 @@ class URShiftVLNode : public VectorNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//------------------------------LShiftCntVNode---------------------------------
|
||||||
|
// Vector left shift count
|
||||||
|
class LShiftCntVNode : public VectorNode {
|
||||||
|
public:
|
||||||
|
LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------RShiftCntVNode---------------------------------
|
||||||
|
// Vector right shift count
|
||||||
|
class RShiftCntVNode : public VectorNode {
|
||||||
|
public:
|
||||||
|
RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//------------------------------AndVNode---------------------------------------
|
//------------------------------AndVNode---------------------------------------
|
||||||
// Vector and integer
|
// Vector and integer
|
||||||
|
@ -452,7 +470,7 @@ class PackNode : public VectorNode {
|
||||||
static PackNode* make(Compile* C, Node* s, uint vlen, BasicType bt);
|
static PackNode* make(Compile* C, Node* s, uint vlen, BasicType bt);
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------PackBNode---------------------------------------
|
//------------------------------PackBNode--------------------------------------
|
||||||
// Pack byte scalars into vector
|
// Pack byte scalars into vector
|
||||||
class PackBNode : public PackNode {
|
class PackBNode : public PackNode {
|
||||||
public:
|
public:
|
||||||
|
@ -460,7 +478,7 @@ class PackBNode : public PackNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------PackSNode---------------------------------------
|
//------------------------------PackSNode--------------------------------------
|
||||||
// Pack short scalars into a vector
|
// Pack short scalars into a vector
|
||||||
class PackSNode : public PackNode {
|
class PackSNode : public PackNode {
|
||||||
public:
|
public:
|
||||||
|
@ -469,7 +487,7 @@ class PackSNode : public PackNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------PackINode---------------------------------------
|
//------------------------------PackINode--------------------------------------
|
||||||
// Pack integer scalars into a vector
|
// Pack integer scalars into a vector
|
||||||
class PackINode : public PackNode {
|
class PackINode : public PackNode {
|
||||||
public:
|
public:
|
||||||
|
@ -478,7 +496,7 @@ class PackINode : public PackNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------PackLNode---------------------------------------
|
//------------------------------PackLNode--------------------------------------
|
||||||
// Pack long scalars into a vector
|
// Pack long scalars into a vector
|
||||||
class PackLNode : public PackNode {
|
class PackLNode : public PackNode {
|
||||||
public:
|
public:
|
||||||
|
@ -487,7 +505,7 @@ class PackLNode : public PackNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------Pack2LNode--------------------------------------
|
//------------------------------Pack2LNode-------------------------------------
|
||||||
// Pack 2 long scalars into a vector
|
// Pack 2 long scalars into a vector
|
||||||
class Pack2LNode : public PackNode {
|
class Pack2LNode : public PackNode {
|
||||||
public:
|
public:
|
||||||
|
@ -495,7 +513,7 @@ class Pack2LNode : public PackNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------PackFNode---------------------------------------
|
//------------------------------PackFNode--------------------------------------
|
||||||
// Pack float scalars into vector
|
// Pack float scalars into vector
|
||||||
class PackFNode : public PackNode {
|
class PackFNode : public PackNode {
|
||||||
public:
|
public:
|
||||||
|
@ -504,7 +522,7 @@ class PackFNode : public PackNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------PackDNode---------------------------------------
|
//------------------------------PackDNode--------------------------------------
|
||||||
// Pack double scalars into a vector
|
// Pack double scalars into a vector
|
||||||
class PackDNode : public PackNode {
|
class PackDNode : public PackNode {
|
||||||
public:
|
public:
|
||||||
|
@ -513,7 +531,7 @@ class PackDNode : public PackNode {
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------Pack2DNode--------------------------------------
|
//------------------------------Pack2DNode-------------------------------------
|
||||||
// Pack 2 double scalars into a vector
|
// Pack 2 double scalars into a vector
|
||||||
class Pack2DNode : public PackNode {
|
class Pack2DNode : public PackNode {
|
||||||
public:
|
public:
|
||||||
|
@ -522,9 +540,9 @@ class Pack2DNode : public PackNode {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//========================Extract_Scalar_from_Vector===============================
|
//========================Extract_Scalar_from_Vector===========================
|
||||||
|
|
||||||
//------------------------------ExtractNode---------------------------------------
|
//------------------------------ExtractNode------------------------------------
|
||||||
// Extract a scalar from a vector at position "pos"
|
// Extract a scalar from a vector at position "pos"
|
||||||
class ExtractNode : public Node {
|
class ExtractNode : public Node {
|
||||||
public:
|
public:
|
||||||
|
@ -537,7 +555,7 @@ class ExtractNode : public Node {
|
||||||
static Node* make(Compile* C, Node* v, uint position, BasicType bt);
|
static Node* make(Compile* C, Node* v, uint position, BasicType bt);
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------ExtractBNode---------------------------------------
|
//------------------------------ExtractBNode-----------------------------------
|
||||||
// Extract a byte from a vector at position "pos"
|
// Extract a byte from a vector at position "pos"
|
||||||
class ExtractBNode : public ExtractNode {
|
class ExtractBNode : public ExtractNode {
|
||||||
public:
|
public:
|
||||||
|
@ -547,7 +565,7 @@ class ExtractBNode : public ExtractNode {
|
||||||
virtual uint ideal_reg() const { return Op_RegI; }
|
virtual uint ideal_reg() const { return Op_RegI; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------ExtractUBNode--------------------------------------
|
//------------------------------ExtractUBNode----------------------------------
|
||||||
// Extract a boolean from a vector at position "pos"
|
// Extract a boolean from a vector at position "pos"
|
||||||
class ExtractUBNode : public ExtractNode {
|
class ExtractUBNode : public ExtractNode {
|
||||||
public:
|
public:
|
||||||
|
@ -557,7 +575,7 @@ class ExtractUBNode : public ExtractNode {
|
||||||
virtual uint ideal_reg() const { return Op_RegI; }
|
virtual uint ideal_reg() const { return Op_RegI; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------ExtractCNode---------------------------------------
|
//------------------------------ExtractCNode-----------------------------------
|
||||||
// Extract a char from a vector at position "pos"
|
// Extract a char from a vector at position "pos"
|
||||||
class ExtractCNode : public ExtractNode {
|
class ExtractCNode : public ExtractNode {
|
||||||
public:
|
public:
|
||||||
|
@ -567,7 +585,7 @@ class ExtractCNode : public ExtractNode {
|
||||||
virtual uint ideal_reg() const { return Op_RegI; }
|
virtual uint ideal_reg() const { return Op_RegI; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------ExtractSNode---------------------------------------
|
//------------------------------ExtractSNode-----------------------------------
|
||||||
// Extract a short from a vector at position "pos"
|
// Extract a short from a vector at position "pos"
|
||||||
class ExtractSNode : public ExtractNode {
|
class ExtractSNode : public ExtractNode {
|
||||||
public:
|
public:
|
||||||
|
@ -577,7 +595,7 @@ class ExtractSNode : public ExtractNode {
|
||||||
virtual uint ideal_reg() const { return Op_RegI; }
|
virtual uint ideal_reg() const { return Op_RegI; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------ExtractINode---------------------------------------
|
//------------------------------ExtractINode-----------------------------------
|
||||||
// Extract an int from a vector at position "pos"
|
// Extract an int from a vector at position "pos"
|
||||||
class ExtractINode : public ExtractNode {
|
class ExtractINode : public ExtractNode {
|
||||||
public:
|
public:
|
||||||
|
@ -587,7 +605,7 @@ class ExtractINode : public ExtractNode {
|
||||||
virtual uint ideal_reg() const { return Op_RegI; }
|
virtual uint ideal_reg() const { return Op_RegI; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------ExtractLNode---------------------------------------
|
//------------------------------ExtractLNode-----------------------------------
|
||||||
// Extract a long from a vector at position "pos"
|
// Extract a long from a vector at position "pos"
|
||||||
class ExtractLNode : public ExtractNode {
|
class ExtractLNode : public ExtractNode {
|
||||||
public:
|
public:
|
||||||
|
@ -597,7 +615,7 @@ class ExtractLNode : public ExtractNode {
|
||||||
virtual uint ideal_reg() const { return Op_RegL; }
|
virtual uint ideal_reg() const { return Op_RegL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------ExtractFNode---------------------------------------
|
//------------------------------ExtractFNode-----------------------------------
|
||||||
// Extract a float from a vector at position "pos"
|
// Extract a float from a vector at position "pos"
|
||||||
class ExtractFNode : public ExtractNode {
|
class ExtractFNode : public ExtractNode {
|
||||||
public:
|
public:
|
||||||
|
@ -607,7 +625,7 @@ class ExtractFNode : public ExtractNode {
|
||||||
virtual uint ideal_reg() const { return Op_RegF; }
|
virtual uint ideal_reg() const { return Op_RegF; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------ExtractDNode---------------------------------------
|
//------------------------------ExtractDNode-----------------------------------
|
||||||
// Extract a double from a vector at position "pos"
|
// Extract a double from a vector at position "pos"
|
||||||
class ExtractDNode : public ExtractNode {
|
class ExtractDNode : public ExtractNode {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -1112,7 +1112,7 @@ void Arguments::set_parnew_gc_flags() {
|
||||||
// AlwaysTenure flag should make ParNew promote all at first collection.
|
// AlwaysTenure flag should make ParNew promote all at first collection.
|
||||||
// See CR 6362902.
|
// See CR 6362902.
|
||||||
if (AlwaysTenure) {
|
if (AlwaysTenure) {
|
||||||
FLAG_SET_CMDLINE(intx, MaxTenuringThreshold, 0);
|
FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, 0);
|
||||||
}
|
}
|
||||||
// When using compressed oops, we use local overflow stacks,
|
// When using compressed oops, we use local overflow stacks,
|
||||||
// rather than using a global overflow list chained through
|
// rather than using a global overflow list chained through
|
||||||
|
@ -1231,7 +1231,7 @@ void Arguments::set_cms_and_parnew_gc_flags() {
|
||||||
// promote all objects surviving "tenuring_default" scavenges.
|
// promote all objects surviving "tenuring_default" scavenges.
|
||||||
if (FLAG_IS_DEFAULT(MaxTenuringThreshold) &&
|
if (FLAG_IS_DEFAULT(MaxTenuringThreshold) &&
|
||||||
FLAG_IS_DEFAULT(SurvivorRatio)) {
|
FLAG_IS_DEFAULT(SurvivorRatio)) {
|
||||||
FLAG_SET_ERGO(intx, MaxTenuringThreshold, tenuring_default);
|
FLAG_SET_ERGO(uintx, MaxTenuringThreshold, tenuring_default);
|
||||||
}
|
}
|
||||||
// If we decided above (or user explicitly requested)
|
// If we decided above (or user explicitly requested)
|
||||||
// `promote all' (via MaxTenuringThreshold := 0),
|
// `promote all' (via MaxTenuringThreshold := 0),
|
||||||
|
|
|
@ -154,7 +154,7 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_
|
||||||
return BiasedLocking::NOT_BIASED;
|
return BiasedLocking::NOT_BIASED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int age = mark->age();
|
uint age = mark->age();
|
||||||
markOop biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
|
markOop biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
|
||||||
markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
|
markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
|
||||||
|
|
||||||
|
|
|
@ -473,7 +473,7 @@ class CommandLineFlags {
|
||||||
develop(bool, CleanChunkPoolAsync, falseInEmbedded, \
|
develop(bool, CleanChunkPoolAsync, falseInEmbedded, \
|
||||||
"Whether to clean the chunk pool asynchronously") \
|
"Whether to clean the chunk pool asynchronously") \
|
||||||
\
|
\
|
||||||
/* Temporary: See 6948537 */ \
|
/* Temporary: See 6948537 */ \
|
||||||
experimental(bool, UseMemSetInBOT, true, \
|
experimental(bool, UseMemSetInBOT, true, \
|
||||||
"(Unstable) uses memset in BOT updates in GC code") \
|
"(Unstable) uses memset in BOT updates in GC code") \
|
||||||
\
|
\
|
||||||
|
@ -1626,7 +1626,7 @@ class CommandLineFlags {
|
||||||
"Use BinaryTreeDictionary as default in the CMS generation") \
|
"Use BinaryTreeDictionary as default in the CMS generation") \
|
||||||
\
|
\
|
||||||
product(uintx, CMSIndexedFreeListReplenish, 4, \
|
product(uintx, CMSIndexedFreeListReplenish, 4, \
|
||||||
"Replenish an indexed free list with this number of chunks") \
|
"Replenish an indexed free list with this number of chunks") \
|
||||||
\
|
\
|
||||||
product(bool, CMSReplenishIntermediate, true, \
|
product(bool, CMSReplenishIntermediate, true, \
|
||||||
"Replenish all intermediate free-list caches") \
|
"Replenish all intermediate free-list caches") \
|
||||||
|
@ -2052,7 +2052,7 @@ class CommandLineFlags {
|
||||||
product(uintx, TenuredGenerationSizeSupplementDecay, 2, \
|
product(uintx, TenuredGenerationSizeSupplementDecay, 2, \
|
||||||
"Decay factor to TenuredGenerationSizeIncrement") \
|
"Decay factor to TenuredGenerationSizeIncrement") \
|
||||||
\
|
\
|
||||||
product(uintx, MaxGCPauseMillis, max_uintx, \
|
product(uintx, MaxGCPauseMillis, max_uintx, \
|
||||||
"Adaptive size policy maximum GC pause time goal in msec, " \
|
"Adaptive size policy maximum GC pause time goal in msec, " \
|
||||||
"or (G1 Only) the max. GC time per MMU time slice") \
|
"or (G1 Only) the max. GC time per MMU time slice") \
|
||||||
\
|
\
|
||||||
|
@ -2266,7 +2266,7 @@ class CommandLineFlags {
|
||||||
develop(bool, TraceGCTaskQueue, false, \
|
develop(bool, TraceGCTaskQueue, false, \
|
||||||
"Trace actions of the GC task queues") \
|
"Trace actions of the GC task queues") \
|
||||||
\
|
\
|
||||||
diagnostic(bool, TraceGCTaskThread, false, \
|
diagnostic(bool, TraceGCTaskThread, false, \
|
||||||
"Trace actions of the GC task threads") \
|
"Trace actions of the GC task threads") \
|
||||||
\
|
\
|
||||||
product(bool, PrintParallelOldGCPhaseTimes, false, \
|
product(bool, PrintParallelOldGCPhaseTimes, false, \
|
||||||
|
@ -2781,7 +2781,7 @@ class CommandLineFlags {
|
||||||
product(intx, SafepointTimeoutDelay, 10000, \
|
product(intx, SafepointTimeoutDelay, 10000, \
|
||||||
"Delay in milliseconds for option SafepointTimeout") \
|
"Delay in milliseconds for option SafepointTimeout") \
|
||||||
\
|
\
|
||||||
product(intx, NmethodSweepFraction, 16, \
|
product(intx, NmethodSweepFraction, 16, \
|
||||||
"Number of invocations of sweeper to cover all nmethods") \
|
"Number of invocations of sweeper to cover all nmethods") \
|
||||||
\
|
\
|
||||||
product(intx, NmethodSweepCheckInterval, 5, \
|
product(intx, NmethodSweepCheckInterval, 5, \
|
||||||
|
@ -2904,7 +2904,7 @@ class CommandLineFlags {
|
||||||
"if non-zero, start verifying C heap after Nth call to " \
|
"if non-zero, start verifying C heap after Nth call to " \
|
||||||
"malloc/realloc/free") \
|
"malloc/realloc/free") \
|
||||||
\
|
\
|
||||||
product(intx, TypeProfileWidth, 2, \
|
product(intx, TypeProfileWidth, 2, \
|
||||||
"number of receiver types to record in call/cast profile") \
|
"number of receiver types to record in call/cast profile") \
|
||||||
\
|
\
|
||||||
develop(intx, BciProfileWidth, 2, \
|
develop(intx, BciProfileWidth, 2, \
|
||||||
|
@ -3012,10 +3012,10 @@ class CommandLineFlags {
|
||||||
product(uintx, MinHeapDeltaBytes, ScaleForWordSize(128*K), \
|
product(uintx, MinHeapDeltaBytes, ScaleForWordSize(128*K), \
|
||||||
"Min change in heap space due to GC (in bytes)") \
|
"Min change in heap space due to GC (in bytes)") \
|
||||||
\
|
\
|
||||||
product(uintx, MinMetaspaceExpansion, ScaleForWordSize(256*K), \
|
product(uintx, MinMetaspaceExpansion, ScaleForWordSize(256*K), \
|
||||||
"Min expansion of permanent heap (in bytes)") \
|
"Min expansion of permanent heap (in bytes)") \
|
||||||
\
|
\
|
||||||
product(uintx, MaxMetaspaceExpansion, ScaleForWordSize(4*M), \
|
product(uintx, MaxMetaspaceExpansion, ScaleForWordSize(4*M), \
|
||||||
"Max expansion of permanent heap without full GC (in bytes)") \
|
"Max expansion of permanent heap without full GC (in bytes)") \
|
||||||
\
|
\
|
||||||
product(intx, QueuedAllocationWarningCount, 0, \
|
product(intx, QueuedAllocationWarningCount, 0, \
|
||||||
|
@ -3028,10 +3028,10 @@ class CommandLineFlags {
|
||||||
diagnostic(intx, VerifyGCLevel, 0, \
|
diagnostic(intx, VerifyGCLevel, 0, \
|
||||||
"Generation level at which to start +VerifyBefore/AfterGC") \
|
"Generation level at which to start +VerifyBefore/AfterGC") \
|
||||||
\
|
\
|
||||||
product(intx, MaxTenuringThreshold, 15, \
|
product(uintx, MaxTenuringThreshold, 15, \
|
||||||
"Maximum value for tenuring threshold") \
|
"Maximum value for tenuring threshold") \
|
||||||
\
|
\
|
||||||
product(intx, InitialTenuringThreshold, 7, \
|
product(uintx, InitialTenuringThreshold, 7, \
|
||||||
"Initial value for tenuring threshold") \
|
"Initial value for tenuring threshold") \
|
||||||
\
|
\
|
||||||
product(intx, TargetSurvivorRatio, 50, \
|
product(intx, TargetSurvivorRatio, 50, \
|
||||||
|
@ -3065,6 +3065,9 @@ class CommandLineFlags {
|
||||||
develop(uintx, GCExpandToAllocateDelayMillis, 0, \
|
develop(uintx, GCExpandToAllocateDelayMillis, 0, \
|
||||||
"Delay in ms between expansion and allocation") \
|
"Delay in ms between expansion and allocation") \
|
||||||
\
|
\
|
||||||
|
develop(uintx, GCWorkerDelayMillis, 0, \
|
||||||
|
"Delay in ms in scheduling GC workers") \
|
||||||
|
\
|
||||||
product(intx, DeferThrSuspendLoopCount, 4000, \
|
product(intx, DeferThrSuspendLoopCount, 4000, \
|
||||||
"(Unstable) Number of times to iterate in safepoint loop " \
|
"(Unstable) Number of times to iterate in safepoint loop " \
|
||||||
" before blocking VM threads ") \
|
" before blocking VM threads ") \
|
||||||
|
|
|
@ -878,6 +878,7 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||||
st->print(" for ");
|
st->print(" for ");
|
||||||
nm->method()->print_value_on(st);
|
nm->method()->print_value_on(st);
|
||||||
}
|
}
|
||||||
|
st->cr();
|
||||||
nm->print_nmethod(verbose);
|
nm->print_nmethod(verbose);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -898,7 +899,11 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||||
print = true;
|
print = true;
|
||||||
}
|
}
|
||||||
if (print) {
|
if (print) {
|
||||||
st->print_cr(INTPTR_FORMAT " is an oop", addr);
|
if (p == (HeapWord*) addr) {
|
||||||
|
st->print_cr(INTPTR_FORMAT " is an oop", addr);
|
||||||
|
} else {
|
||||||
|
st->print_cr(INTPTR_FORMAT " is pointing into object: " INTPTR_FORMAT, addr, p);
|
||||||
|
}
|
||||||
oop(p)->print_on(st);
|
oop(p)->print_on(st);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -508,7 +508,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
|
||||||
nonstatic_field(ContiguousSpace, _saved_mark_word, HeapWord*) \
|
nonstatic_field(ContiguousSpace, _saved_mark_word, HeapWord*) \
|
||||||
\
|
\
|
||||||
nonstatic_field(DefNewGeneration, _next_gen, Generation*) \
|
nonstatic_field(DefNewGeneration, _next_gen, Generation*) \
|
||||||
nonstatic_field(DefNewGeneration, _tenuring_threshold, int) \
|
nonstatic_field(DefNewGeneration, _tenuring_threshold, uint) \
|
||||||
nonstatic_field(DefNewGeneration, _age_table, ageTable) \
|
nonstatic_field(DefNewGeneration, _age_table, ageTable) \
|
||||||
nonstatic_field(DefNewGeneration, _eden_space, EdenSpace*) \
|
nonstatic_field(DefNewGeneration, _eden_space, EdenSpace*) \
|
||||||
nonstatic_field(DefNewGeneration, _from_space, ContiguousSpace*) \
|
nonstatic_field(DefNewGeneration, _from_space, ContiguousSpace*) \
|
||||||
|
|
54
hotspot/test/compiler/7199742/Test7199742.java
Normal file
54
hotspot/test/compiler/7199742/Test7199742.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, 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 7199742
|
||||||
|
* @summary A lot of C2 OSR compilations of the same method's bci
|
||||||
|
*
|
||||||
|
* @run main/othervm -Xmx32m -Xbatch Test7199742
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Test7199742 {
|
||||||
|
private static final int ITERS = 10000000;
|
||||||
|
public static void main(String args[]) {
|
||||||
|
Test7199742 t = new Test7199742();
|
||||||
|
for (int i=0; i<10; i++) {
|
||||||
|
test(t, 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static Test7199742 test(Test7199742 t, int m) {
|
||||||
|
int i = -(ITERS/2);
|
||||||
|
if (i == 0) return null;
|
||||||
|
Test7199742 v = null;
|
||||||
|
while(i < ITERS) {
|
||||||
|
if ((i&m) == 0) {
|
||||||
|
v = t;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -77,6 +77,16 @@ then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# grep for support integer multiply vectors (cpu with SSE4.1)
|
||||||
|
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -XX:+PrintMiscellaneous -XX:+Verbose -version | grep "cores per cpu" | grep "sse4.1"
|
||||||
|
|
||||||
|
if [ $? != 0 ]
|
||||||
|
then
|
||||||
|
SSE=2
|
||||||
|
else
|
||||||
|
SSE=4
|
||||||
|
fi
|
||||||
|
|
||||||
cp ${TESTSRC}${FS}TestIntVect.java .
|
cp ${TESTSRC}${FS}TestIntVect.java .
|
||||||
${TESTJAVA}${FS}bin${FS}javac -d . TestIntVect.java
|
${TESTJAVA}${FS}bin${FS}javac -d . TestIntVect.java
|
||||||
|
|
||||||
|
@ -97,6 +107,9 @@ then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# MulVI is only supported with SSE4.1.
|
||||||
|
if [ $SSE -gt 3 ]
|
||||||
|
then
|
||||||
# LShiftVI+SubVI is generated for test_mulc
|
# LShiftVI+SubVI is generated for test_mulc
|
||||||
COUNT=`grep MulVI test.out | wc -l | awk '{print $1}'`
|
COUNT=`grep MulVI test.out | wc -l | awk '{print $1}'`
|
||||||
if [ $COUNT -lt 2 ]
|
if [ $COUNT -lt 2 ]
|
||||||
|
@ -104,6 +117,7 @@ then
|
||||||
echo "Test Failed: MulVI $COUNT < 2"
|
echo "Test Failed: MulVI $COUNT < 2"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
COUNT=`grep AndV test.out | wc -l | awk '{print $1}'`
|
COUNT=`grep AndV test.out | wc -l | awk '{print $1}'`
|
||||||
if [ $COUNT -lt 3 ]
|
if [ $COUNT -lt 3 ]
|
||||||
|
@ -126,6 +140,7 @@ then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# LShiftVI+SubVI is generated for test_mulc
|
||||||
COUNT=`grep LShiftVI test.out | wc -l | awk '{print $1}'`
|
COUNT=`grep LShiftVI test.out | wc -l | awk '{print $1}'`
|
||||||
if [ $COUNT -lt 5 ]
|
if [ $COUNT -lt 5 ]
|
||||||
then
|
then
|
||||||
|
@ -133,11 +148,10 @@ then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# RShiftVI + URShiftVI
|
COUNT=`grep RShiftVI test.out | sed '/URShiftVI/d' | wc -l | awk '{print $1}'`
|
||||||
COUNT=`grep RShiftVI test.out | wc -l | awk '{print $1}'`
|
if [ $COUNT -lt 3 ]
|
||||||
if [ $COUNT -lt 6 ]
|
|
||||||
then
|
then
|
||||||
echo "Test Failed: RShiftVI $COUNT < 6"
|
echo "Test Failed: RShiftVI $COUNT < 3"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -180,3 +180,4 @@ bd3c00d5761408954cc29ffb82016a76cbc90b43 jdk8-b52
|
||||||
f19d63b2119a0092f016203981ffef5cc31bc3c5 jdk8-b56
|
f19d63b2119a0092f016203981ffef5cc31bc3c5 jdk8-b56
|
||||||
7c9475c7618cb131bcd7470f859bf43c5e5f9905 jdk8-b57
|
7c9475c7618cb131bcd7470f859bf43c5e5f9905 jdk8-b57
|
||||||
1cb19abb3f7b40bf233b349cd2f51f02d37a9f5b jdk8-b58
|
1cb19abb3f7b40bf233b349cd2f51f02d37a9f5b jdk8-b58
|
||||||
|
af9e8b0f1900b631a8a0fcccff9f1514fe58c808 jdk8-b59
|
||||||
|
|
|
@ -180,3 +180,4 @@ f62bc618122e87a8bea69865cc02074e9d850426 jdk8-b52
|
||||||
7813455ccdb08c3ee6051161176821325a5d44d7 jdk8-b56
|
7813455ccdb08c3ee6051161176821325a5d44d7 jdk8-b56
|
||||||
b51b611209f159f94dd2ce3dc2c56daa6d6ac1df jdk8-b57
|
b51b611209f159f94dd2ce3dc2c56daa6d6ac1df jdk8-b57
|
||||||
cac4c393706343df778a13dc6c84cad0f8c237c9 jdk8-b58
|
cac4c393706343df778a13dc6c84cad0f8c237c9 jdk8-b58
|
||||||
|
ae107401be116f9e384d3a23192f543828e03da5 jdk8-b59
|
||||||
|
|
|
@ -180,3 +180,4 @@ e8569a473cee7f4955bd9e76a9bdf6c6a07ced27 jdk8-b52
|
||||||
2e9eeef2909b33c9224a024afddb61ccb0b77f14 jdk8-b56
|
2e9eeef2909b33c9224a024afddb61ccb0b77f14 jdk8-b56
|
||||||
51594d095a4bcffac4a314bf6e148214501399e0 jdk8-b57
|
51594d095a4bcffac4a314bf6e148214501399e0 jdk8-b57
|
||||||
d94613ac03d8de375ef60493e2bb76dbd30d875d jdk8-b58
|
d94613ac03d8de375ef60493e2bb76dbd30d875d jdk8-b58
|
||||||
|
abad1f417bd3df4296631fc943cd3b7f5062c88a jdk8-b59
|
||||||
|
|
|
@ -180,3 +180,4 @@ e48e7e1f026b82d921433150180799898c088890 jdk8-b55
|
||||||
363e9198b9de68ebf37a3e2c2f3f23543d3915cd jdk8-b56
|
363e9198b9de68ebf37a3e2c2f3f23543d3915cd jdk8-b56
|
||||||
86d5740b9fdc20ababb8aefde89ae1509ff216a9 jdk8-b57
|
86d5740b9fdc20ababb8aefde89ae1509ff216a9 jdk8-b57
|
||||||
804a3fbc86e28a4d9e77c30aa0bd4aa68056f23f jdk8-b58
|
804a3fbc86e28a4d9e77c30aa0bd4aa68056f23f jdk8-b58
|
||||||
|
f299927fc31689385f67ab7322c18eb41d8bd71e jdk8-b59
|
||||||
|
|
|
@ -330,6 +330,10 @@ COMMON_BUILD_ARGUMENTS = \
|
||||||
PREVIOUS_MINOR_VERSION=$(PREVIOUS_MINOR_VERSION) \
|
PREVIOUS_MINOR_VERSION=$(PREVIOUS_MINOR_VERSION) \
|
||||||
PREVIOUS_MICRO_VERSION=$(PREVIOUS_MICRO_VERSION)
|
PREVIOUS_MICRO_VERSION=$(PREVIOUS_MICRO_VERSION)
|
||||||
|
|
||||||
|
ifdef OPENJDK
|
||||||
|
COMMON_BUILD_ARGUMENTS += OPENJDK=$(OPENJDK)
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef ARCH_DATA_MODEL
|
ifdef ARCH_DATA_MODEL
|
||||||
COMMON_BUILD_ARGUMENTS += ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)
|
COMMON_BUILD_ARGUMENTS += ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)
|
||||||
endif
|
endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue