35 #include "vmreg_s390.inline.hpp" |
35 #include "vmreg_s390.inline.hpp" |
36 #ifdef COMPILER2 |
36 #ifdef COMPILER2 |
37 #include "opto/runtime.hpp" |
37 #include "opto/runtime.hpp" |
38 #endif |
38 #endif |
39 |
39 |
40 // Machine-dependent part of VtableStubs: create vtableStub of correct |
|
41 // size and initialize its code. |
|
42 |
|
43 #define __ masm-> |
40 #define __ masm-> |
44 |
41 |
45 #ifndef PRODUCT |
42 #ifndef PRODUCT |
46 extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int index); |
43 extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int index); |
47 #endif |
44 #endif |
48 |
45 |
49 // Used by compiler only; may use only caller saved, non-argument registers. |
46 // Used by compiler only; may use only caller saved, non-argument registers. |
50 VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { |
47 VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { |
51 |
48 // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing. |
52 const int code_length = VtableStub::pd_code_size_limit(true); |
49 const int stub_code_length = code_size_limit(true); |
53 VtableStub *s = new(code_length) VtableStub(true, vtable_index); |
50 VtableStub* s = new(stub_code_length) VtableStub(true, vtable_index); |
54 if (s == NULL) { // Indicates OOM In the code cache. |
51 // Can be NULL if there is no free space in the code cache. |
|
52 if (s == NULL) { |
55 return NULL; |
53 return NULL; |
56 } |
54 } |
57 |
55 |
|
56 // Count unused bytes in instruction sequences of variable size. |
|
57 // We add them to the computed buffer size in order to avoid |
|
58 // overflow in subsequently generated stubs. |
|
59 address start_pc; |
|
60 int slop_bytes = 0; |
|
61 int slop_delta = 0; |
|
62 |
58 ResourceMark rm; |
63 ResourceMark rm; |
59 CodeBuffer cb(s->entry_point(), code_length); |
64 CodeBuffer cb(s->entry_point(), stub_code_length); |
60 MacroAssembler *masm = new MacroAssembler(&cb); |
65 MacroAssembler* masm = new MacroAssembler(&cb); |
61 int padding_bytes = 0; |
|
62 |
66 |
63 #if (!defined(PRODUCT) && defined(COMPILER2)) |
67 #if (!defined(PRODUCT) && defined(COMPILER2)) |
64 if (CountCompiledCalls) { |
68 if (CountCompiledCalls) { |
65 // Count unused bytes |
69 // worst case actual size |
66 // worst case actual size |
70 slop_delta = __ load_const_size() - __ load_const_optimized_rtn_len(Z_R1_scratch, (long)SharedRuntime::nof_megamorphic_calls_addr(), true); |
67 padding_bytes += __ load_const_size() - __ load_const_optimized_rtn_len(Z_R1_scratch, (long)SharedRuntime::nof_megamorphic_calls_addr(), true); |
71 slop_bytes += slop_delta; |
68 |
72 assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta); |
69 // Use generic emitter for direct memory increment. |
73 // Use generic emitter for direct memory increment. |
70 // Abuse Z_method as scratch register for generic emitter. |
74 // Abuse Z_method as scratch register for generic emitter. |
71 // It is loaded further down anyway before it is first used. |
75 // It is loaded further down anyway before it is first used. |
|
76 // No dynamic code size variance here, increment is 1, always. |
72 __ add2mem_32(Address(Z_R1_scratch), 1, Z_method); |
77 __ add2mem_32(Address(Z_R1_scratch), 1, Z_method); |
73 } |
78 } |
74 #endif |
79 #endif |
75 |
80 |
76 assert(VtableStub::receiver_location() == Z_R2->as_VMReg(), "receiver expected in Z_ARG1"); |
81 assert(VtableStub::receiver_location() == Z_R2->as_VMReg(), "receiver expected in Z_ARG1"); |
77 |
82 |
|
83 const Register rcvr_klass = Z_R1_scratch; |
|
84 address npe_addr = __ pc(); // npe == NULL ptr exception |
|
85 // check if we must do an explicit check (implicit checks disabled, offset too large). |
|
86 __ null_check(Z_ARG1, Z_R1_scratch, oopDesc::klass_offset_in_bytes()); |
78 // Get receiver klass. |
87 // Get receiver klass. |
79 // Must do an explicit check if implicit checks are disabled. |
|
80 address npe_addr = __ pc(); // npe == NULL ptr exception |
|
81 __ null_check(Z_ARG1, Z_R1_scratch, oopDesc::klass_offset_in_bytes()); |
|
82 const Register rcvr_klass = Z_R1_scratch; |
|
83 __ load_klass(rcvr_klass, Z_ARG1); |
88 __ load_klass(rcvr_klass, Z_ARG1); |
84 |
89 |
85 // Set method (in case of interpreted method), and destination address. |
|
86 int entry_offset = in_bytes(Klass::vtable_start_offset()) + |
|
87 vtable_index * vtableEntry::size_in_bytes(); |
|
88 |
|
89 #ifndef PRODUCT |
90 #ifndef PRODUCT |
90 if (DebugVtables) { |
91 if (DebugVtables) { |
91 Label L; |
92 NearLabel L; |
92 // Check offset vs vtable length. |
93 // Check offset vs vtable length. |
93 const Register vtable_idx = Z_R0_scratch; |
94 const Register vtable_idx = Z_R0_scratch; |
94 |
95 |
95 // Count unused bytes. |
96 // worst case actual size |
96 // worst case actual size |
97 slop_delta = __ load_const_size() - __ load_const_optimized_rtn_len(vtable_idx, vtable_index*vtableEntry::size(), true); |
97 padding_bytes += __ load_const_size() - __ load_const_optimized_rtn_len(vtable_idx, vtable_index*vtableEntry::size_in_bytes(), true); |
98 slop_bytes += slop_delta; |
98 |
99 assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta); |
99 assert(Immediate::is_uimm12(in_bytes(Klass::vtable_length_offset())), "disp to large"); |
100 |
|
101 assert(Displacement::is_shortDisp(in_bytes(Klass::vtable_length_offset())), "disp to large"); |
100 __ z_cl(vtable_idx, in_bytes(Klass::vtable_length_offset()), rcvr_klass); |
102 __ z_cl(vtable_idx, in_bytes(Klass::vtable_length_offset()), rcvr_klass); |
101 __ z_brl(L); |
103 __ z_brl(L); |
102 __ z_lghi(Z_ARG3, vtable_index); // Debug code, don't optimize. |
104 __ z_lghi(Z_ARG3, vtable_index); // Debug code, don't optimize. |
103 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), Z_ARG1, Z_ARG3, false); |
105 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), Z_ARG1, Z_ARG3, false); |
104 // Count unused bytes (assume worst case here). |
106 // Count unused bytes (assume worst case here). |
105 padding_bytes += 12; |
107 slop_bytes += 12; |
106 __ bind(L); |
108 __ bind(L); |
107 } |
109 } |
108 #endif |
110 #endif |
109 |
111 |
110 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); |
112 int entry_offset = in_bytes(Klass::vtable_start_offset()) + |
111 |
113 vtable_index * vtableEntry::size_in_bytes(); |
|
114 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); |
|
115 |
|
116 // Set method (in case of interpreted method), and destination address. |
112 // Duplicate safety code from enc_class Java_Dynamic_Call_dynTOC. |
117 // Duplicate safety code from enc_class Java_Dynamic_Call_dynTOC. |
113 if (Displacement::is_validDisp(v_off)) { |
118 if (Displacement::is_validDisp(v_off)) { |
114 __ z_lg(Z_method/*method oop*/, v_off, rcvr_klass/*class oop*/); |
119 __ z_lg(Z_method/*method oop*/, v_off, rcvr_klass/*class oop*/); |
115 // Account for the load_const in the else path. |
120 // Account for the load_const in the else path. |
116 padding_bytes += __ load_const_size(); |
121 slop_delta = __ load_const_size(); |
117 } else { |
122 } else { |
118 // Worse case, offset does not fit in displacement field. |
123 // Worse case, offset does not fit in displacement field. |
119 __ load_const(Z_method, v_off); // Z_method temporarily holds the offset value. |
124 // worst case actual size |
|
125 slop_delta = __ load_const_size() - __ load_const_optimized_rtn_len(Z_method, v_off, true); |
120 __ z_lg(Z_method/*method oop*/, 0, Z_method/*method offset*/, rcvr_klass/*class oop*/); |
126 __ z_lg(Z_method/*method oop*/, 0, Z_method/*method offset*/, rcvr_klass/*class oop*/); |
121 } |
127 } |
|
128 slop_bytes += slop_delta; |
122 |
129 |
123 #ifndef PRODUCT |
130 #ifndef PRODUCT |
124 if (DebugVtables) { |
131 if (DebugVtables) { |
125 Label L; |
132 NearLabel L; |
126 __ z_ltgr(Z_method, Z_method); |
133 __ z_ltgr(Z_method, Z_method); |
127 __ z_brne(L); |
134 __ z_brne(L); |
128 __ stop("Vtable entry is ZERO",102); |
135 __ stop("Vtable entry is ZERO", 102); |
129 __ bind(L); |
136 __ bind(L); |
130 } |
137 } |
131 #endif |
138 #endif |
132 |
139 |
133 address ame_addr = __ pc(); // ame = abstract method error |
140 // Must do an explicit check if offset too large or implicit checks are disabled. |
134 |
141 address ame_addr = __ pc(); |
135 // Must do an explicit check if implicit checks are disabled. |
|
136 __ null_check(Z_method, Z_R1_scratch, in_bytes(Method::from_compiled_offset())); |
142 __ null_check(Z_method, Z_R1_scratch, in_bytes(Method::from_compiled_offset())); |
137 __ z_lg(Z_R1_scratch, in_bytes(Method::from_compiled_offset()), Z_method); |
143 __ z_lg(Z_R1_scratch, in_bytes(Method::from_compiled_offset()), Z_method); |
138 __ z_br(Z_R1_scratch); |
144 __ z_br(Z_R1_scratch); |
139 |
145 |
140 masm->flush(); |
146 masm->flush(); |
141 |
147 bookkeeping(masm, tty, s, npe_addr, ame_addr, true, vtable_index, slop_bytes, 0); |
142 s->set_exception_points(npe_addr, ame_addr); |
|
143 |
148 |
144 return s; |
149 return s; |
145 } |
150 } |
146 |
151 |
147 VtableStub* VtableStubs::create_itable_stub(int itable_index) { |
152 VtableStub* VtableStubs::create_itable_stub(int itable_index) { |
148 const int code_length = VtableStub::pd_code_size_limit(false); |
153 // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing. |
149 VtableStub *s = new(code_length) VtableStub(false, itable_index); |
154 const int stub_code_length = code_size_limit(false); |
150 if (s == NULL) { // Indicates OOM in the code cache. |
155 VtableStub* s = new(stub_code_length) VtableStub(false, itable_index); |
|
156 // Can be NULL if there is no free space in the code cache. |
|
157 if (s == NULL) { |
151 return NULL; |
158 return NULL; |
152 } |
159 } |
|
160 // Count unused bytes in instruction sequences of variable size. |
|
161 // We add them to the computed buffer size in order to avoid |
|
162 // overflow in subsequently generated stubs. |
|
163 address start_pc; |
|
164 int slop_bytes = 0; |
|
165 int slop_delta = 0; |
153 |
166 |
154 ResourceMark rm; |
167 ResourceMark rm; |
155 CodeBuffer cb(s->entry_point(), code_length); |
168 CodeBuffer cb(s->entry_point(), stub_code_length); |
156 MacroAssembler *masm = new MacroAssembler(&cb); |
169 MacroAssembler* masm = new MacroAssembler(&cb); |
157 int padding_bytes = 0; |
|
158 |
170 |
159 #if (!defined(PRODUCT) && defined(COMPILER2)) |
171 #if (!defined(PRODUCT) && defined(COMPILER2)) |
160 if (CountCompiledCalls) { |
172 if (CountCompiledCalls) { |
161 // Count unused bytes |
173 // worst case actual size |
162 // worst case actual size |
174 slop_delta = __ load_const_size() - __ load_const_optimized_rtn_len(Z_R1_scratch, (long)SharedRuntime::nof_megamorphic_calls_addr(), true); |
163 padding_bytes += __ load_const_size() - __ load_const_optimized_rtn_len(Z_R1_scratch, (long)SharedRuntime::nof_megamorphic_calls_addr(), true); |
175 slop_bytes += slop_delta; |
164 |
176 assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta); |
165 // Use generic emitter for direct memory increment. |
177 // Use generic emitter for direct memory increment. |
166 // Use Z_tmp_1 as scratch register for generic emitter. |
178 // Abuse Z_method as scratch register for generic emitter. |
167 __ add2mem_32((Z_R1_scratch), 1, Z_tmp_1); |
179 // It is loaded further down anyway before it is first used. |
|
180 // No dynamic code size variance here, increment is 1, always. |
|
181 __ add2mem_32(Address(Z_R1_scratch), 1, Z_method); |
168 } |
182 } |
169 #endif |
183 #endif |
170 |
184 |
171 assert(VtableStub::receiver_location() == Z_R2->as_VMReg(), "receiver expected in Z_ARG1"); |
185 assert(VtableStub::receiver_location() == Z_R2->as_VMReg(), "receiver expected in Z_ARG1"); |
172 |
186 |
211 __ z_lg(Z_R1_scratch, in_bytes(Method::from_compiled_offset()), Z_method); |
225 __ z_lg(Z_R1_scratch, in_bytes(Method::from_compiled_offset()), Z_method); |
212 __ z_br(Z_R1_scratch); |
226 __ z_br(Z_R1_scratch); |
213 |
227 |
214 // Handle IncompatibleClassChangeError in itable stubs. |
228 // Handle IncompatibleClassChangeError in itable stubs. |
215 __ bind(no_such_interface); |
229 __ bind(no_such_interface); |
216 // Count unused bytes |
230 // more detailed IncompatibleClassChangeError |
217 // worst case actual size |
231 // we force re-resolving of the call site by jumping to |
218 // We force resolving of the call site by jumping to |
232 // the "handle wrong method" stub, thus letting the |
219 // the "handle wrong method" stub, and so let the |
|
220 // interpreter runtime do all the dirty work. |
233 // interpreter runtime do all the dirty work. |
221 padding_bytes += __ load_const_size() - __ load_const_optimized_rtn_len(Z_R1_scratch, (long)SharedRuntime::get_handle_wrong_method_stub(), true); |
234 // worst case actual size |
|
235 slop_delta = __ load_const_size() - __ load_const_optimized_rtn_len(Z_R1_scratch, (long)SharedRuntime::get_handle_wrong_method_stub(), true); |
|
236 slop_bytes += slop_delta; |
|
237 assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta); |
222 __ z_br(Z_R1_scratch); |
238 __ z_br(Z_R1_scratch); |
223 |
239 |
224 masm->flush(); |
240 masm->flush(); |
225 |
241 bookkeeping(masm, tty, s, npe_addr, ame_addr, false, itable_index, slop_bytes, 0); |
226 s->set_exception_points(npe_addr, ame_addr); |
242 |
227 return s; |
243 return s; |
228 } |
244 } |
229 |
245 |
230 // In order to tune these parameters, run the JVM with VM options |
|
231 // +PrintMiscellaneous and +WizardMode to see information about |
|
232 // actual itable stubs. Run it with -Xmx31G -XX:+UseCompressedOops. |
|
233 int VtableStub::pd_code_size_limit(bool is_vtable_stub) { |
|
234 int size = DebugVtables ? 216 : 0; |
|
235 if (CountCompiledCalls) { |
|
236 size += 6 * 4; |
|
237 } |
|
238 size += is_vtable_stub ? 36 : 140; |
|
239 if (UseCompressedClassPointers) { |
|
240 size += MacroAssembler::instr_size_for_decode_klass_not_null(); |
|
241 } |
|
242 if (!ImplicitNullChecks) { |
|
243 size += 36; |
|
244 } |
|
245 return size; |
|
246 } |
|
247 |
|
248 int VtableStub::pd_code_alignment() { |
246 int VtableStub::pd_code_alignment() { |
|
247 // System z cache line size is 256 bytes, but octoword-alignment is quite ok. |
249 const unsigned int icache_line_size = 32; |
248 const unsigned int icache_line_size = 32; |
250 return icache_line_size; |
249 return icache_line_size; |
251 } |
250 } |