@@ -42,23 +42,25 @@ class DowncallStubGenerator : public StubCodeGenerator {
4242 BasicType _ret_bt;
4343 const ABIDescriptor& _abi;
4444
45- const GrowableArray<VMReg >& _input_registers;
46- const GrowableArray<VMReg >& _output_registers;
45+ const GrowableArray<VMStorage >& _input_registers;
46+ const GrowableArray<VMStorage >& _output_registers;
4747
4848 bool _needs_return_buffer;
49+ int _captured_state_mask;
4950
5051 int _frame_complete;
51- int _framesize ;
52+ int _frame_size_slots ;
5253 OopMapSet* _oop_maps;
5354public:
5455 DowncallStubGenerator (CodeBuffer* buffer,
5556 BasicType* signature,
5657 int num_args,
5758 BasicType ret_bt,
5859 const ABIDescriptor& abi,
59- const GrowableArray<VMReg>& input_registers,
60- const GrowableArray<VMReg>& output_registers,
61- bool needs_return_buffer)
60+ const GrowableArray<VMStorage>& input_registers,
61+ const GrowableArray<VMStorage>& output_registers,
62+ bool needs_return_buffer,
63+ int captured_state_mask)
6264 : StubCodeGenerator(buffer, PrintMethodHandleStubs),
6365 _signature (signature),
6466 _num_args(num_args),
@@ -67,8 +69,9 @@ class DowncallStubGenerator : public StubCodeGenerator {
6769 _input_registers(input_registers),
6870 _output_registers(output_registers),
6971 _needs_return_buffer(needs_return_buffer),
72+ _captured_state_mask(captured_state_mask),
7073 _frame_complete(0 ),
71- _framesize (0 ),
74+ _frame_size_slots (0 ),
7275 _oop_maps(NULL ) {
7376 }
7477
@@ -79,7 +82,7 @@ class DowncallStubGenerator : public StubCodeGenerator {
7982 }
8083
8184 int framesize () const {
82- return (_framesize >> (LogBytesPerWord - LogBytesPerInt));
85+ return (_frame_size_slots >> (LogBytesPerWord - LogBytesPerInt));
8386 }
8487
8588 OopMapSet* oop_maps () const {
@@ -93,12 +96,15 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature,
9396 int num_args,
9497 BasicType ret_bt,
9598 const ABIDescriptor& abi,
96- const GrowableArray<VMReg>& input_registers,
97- const GrowableArray<VMReg>& output_registers,
98- bool needs_return_buffer) {
99- int locs_size = 64 ;
99+ const GrowableArray<VMStorage>& input_registers,
100+ const GrowableArray<VMStorage>& output_registers,
101+ bool needs_return_buffer,
102+ int captured_state_mask) {
103+ int locs_size = 64 ;
100104 CodeBuffer code (" nep_invoker_blob" , native_invoker_code_size, locs_size);
101- DowncallStubGenerator g (&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer);
105+ DowncallStubGenerator g (&code, signature, num_args, ret_bt, abi,
106+ input_registers, output_registers,
107+ needs_return_buffer, captured_state_mask);
102108 g.generate ();
103109 code.log_section_sizes (" nep_invoker_blob" );
104110
@@ -137,10 +143,10 @@ void DowncallStubGenerator::generate() {
137143 Register tmp1 = r9;
138144 Register tmp2 = r10;
139145
140- Register shuffle_reg = r19;
146+ VMStorage shuffle_reg = as_VMStorage ( r19) ;
141147 JavaCallingConvention in_conv;
142148 NativeCallingConvention out_conv (_input_registers);
143- ArgumentShuffle arg_shuffle (_signature, _num_args, _signature, _num_args, &in_conv, &out_conv, shuffle_reg-> as_VMReg () );
149+ ArgumentShuffle arg_shuffle (_signature, _num_args, _signature, _num_args, &in_conv, &out_conv, shuffle_reg);
144150
145151#ifndef PRODUCT
146152 LogTarget (Trace, foreign, downcall) lt;
@@ -152,46 +158,50 @@ void DowncallStubGenerator::generate() {
152158#endif
153159
154160 int allocated_frame_size = 0 ;
155- if (_needs_return_buffer) {
156- allocated_frame_size += 8 ; // for address spill
157- }
158- allocated_frame_size += arg_shuffle.out_arg_stack_slots () <<LogBytesPerInt;
159161 assert (_abi._shadow_space_bytes == 0 , " not expecting shadow space on AArch64" );
162+ allocated_frame_size += arg_shuffle.out_arg_bytes ();
160163
161- int ret_buf_addr_sp_offset = -1 ;
162- if (_needs_return_buffer) {
163- // in sync with the above
164- ret_buf_addr_sp_offset = allocated_frame_size - 8 ;
165- }
166-
164+ bool should_save_return_value = !_needs_return_buffer;
167165 RegSpiller out_reg_spiller (_output_registers);
168166 int spill_offset = -1 ;
169167
170- if (!_needs_return_buffer ) {
168+ if (should_save_return_value ) {
171169 spill_offset = 0 ;
172- // spill area can be shared with the above, so we take the max of the 2
170+ // spill area can be shared with shadow space and out args,
171+ // since they are only used before the call,
172+ // and spill area is only used after.
173173 allocated_frame_size = out_reg_spiller.spill_size_bytes () > allocated_frame_size
174174 ? out_reg_spiller.spill_size_bytes ()
175175 : allocated_frame_size;
176176 }
177177
178- _framesize = align_up (framesize
179- + (allocated_frame_size >> LogBytesPerInt), 4 );
180- assert (is_even (_framesize/2 ), " sp not 16-byte aligned" );
178+ StubLocations locs;
179+ locs.set (StubLocations::TARGET_ADDRESS, _abi._scratch1 );
180+ if (_needs_return_buffer) {
181+ locs.set_frame_data (StubLocations::RETURN_BUFFER, allocated_frame_size);
182+ allocated_frame_size += BytesPerWord; // for address spill
183+ }
184+ if (_captured_state_mask != 0 ) {
185+ locs.set_frame_data (StubLocations::CAPTURED_STATE_BUFFER, allocated_frame_size);
186+ allocated_frame_size += BytesPerWord;
187+ }
188+
189+ _frame_size_slots = align_up (framesize + (allocated_frame_size >> LogBytesPerInt), 4 );
190+ assert (is_even (_frame_size_slots/2 ), " sp not 16-byte aligned" );
181191
182192 _oop_maps = new OopMapSet ();
183193 address start = __ pc ();
184194
185195 __ enter ();
186196
187197 // lr and fp are already in place
188- __ sub (sp, rfp, ((unsigned )_framesize -4 ) << LogBytesPerInt); // prolog
198+ __ sub (sp, rfp, ((unsigned )_frame_size_slots -4 ) << LogBytesPerInt); // prolog
189199
190200 _frame_complete = __ pc () - start;
191201
192202 address the_pc = __ pc ();
193203 __ set_last_Java_frame (sp, rfp, the_pc, tmp1);
194- OopMap* map = new OopMap (_framesize , 0 );
204+ OopMap* map = new OopMap (_frame_size_slots , 0 );
195205 _oop_maps->add_gc_map (the_pc - start, map);
196206
197207 // State transition
@@ -200,34 +210,51 @@ void DowncallStubGenerator::generate() {
200210 __ stlrw (tmp1, tmp2);
201211
202212 __ block_comment (" { argument shuffle" );
203- arg_shuffle.generate (_masm, shuffle_reg->as_VMReg (), 0 , _abi._shadow_space_bytes );
204- if (_needs_return_buffer) {
205- assert (ret_buf_addr_sp_offset != -1 , " no return buffer addr spill" );
206- __ str (_abi._ret_buf_addr_reg , Address (sp, ret_buf_addr_sp_offset));
207- }
213+ arg_shuffle.generate (_masm, shuffle_reg, 0 , _abi._shadow_space_bytes , locs);
208214 __ block_comment (" } argument shuffle" );
209215
210- __ blr (_abi. _target_addr_reg );
216+ __ blr (as_Register (locs. get (StubLocations::TARGET_ADDRESS)) );
211217 // this call is assumed not to have killed rthread
212218
213219 if (_needs_return_buffer) {
214- assert (ret_buf_addr_sp_offset != -1 , " no return buffer addr spill" );
215- __ ldr (tmp1, Address (sp, ret_buf_addr_sp_offset));
220+ __ ldr (tmp1, Address (sp, locs.data_offset (StubLocations::RETURN_BUFFER)));
216221 int offset = 0 ;
217222 for (int i = 0 ; i < _output_registers.length (); i++) {
218- VMReg reg = _output_registers.at (i);
219- if (reg-> is_Register () ) {
220- __ str (reg-> as_Register (), Address (tmp1, offset));
223+ VMStorage reg = _output_registers.at (i);
224+ if (reg. type () == StorageType::INTEGER ) {
225+ __ str (as_Register (reg ), Address (tmp1, offset));
221226 offset += 8 ;
222- } else if (reg-> is_FloatRegister () ) {
223- __ strd (reg-> as_FloatRegister (), Address (tmp1, offset));
227+ } else if (reg. type () == StorageType::VECTOR ) {
228+ __ strd (as_FloatRegister (reg ), Address (tmp1, offset));
224229 offset += 16 ;
225230 } else {
226231 ShouldNotReachHere ();
227232 }
228233 }
229234 }
230235
236+ // ////////////////////////////////////////////////////////////////////////////
237+
238+ if (_captured_state_mask != 0 ) {
239+ __ block_comment (" { save thread local" );
240+
241+ if (should_save_return_value) {
242+ out_reg_spiller.generate_spill (_masm, spill_offset);
243+ }
244+
245+ __ ldr (c_rarg0, Address (sp, locs.data_offset (StubLocations::CAPTURED_STATE_BUFFER)));
246+ __ movw (c_rarg1, _captured_state_mask);
247+ __ rt_call (CAST_FROM_FN_PTR (address, DowncallLinker::capture_state), tmp1);
248+
249+ if (should_save_return_value) {
250+ out_reg_spiller.generate_fill (_masm, spill_offset);
251+ }
252+
253+ __ block_comment (" } save thread local" );
254+ }
255+
256+ // ////////////////////////////////////////////////////////////////////////////
257+
231258 __ mov (tmp1, _thread_in_native_trans);
232259 __ strw (tmp1, Address (rthread, JavaThread::thread_state_offset ()));
233260
@@ -272,7 +299,7 @@ void DowncallStubGenerator::generate() {
272299 __ block_comment (" { L_safepoint_poll_slow_path" );
273300 __ bind (L_safepoint_poll_slow_path);
274301
275- if (!_needs_return_buffer ) {
302+ if (should_save_return_value ) {
276303 // Need to save the native result registers around any runtime calls.
277304 out_reg_spiller.generate_spill (_masm, spill_offset);
278305 }
@@ -282,7 +309,7 @@ void DowncallStubGenerator::generate() {
282309 __ lea (tmp1, RuntimeAddress (CAST_FROM_FN_PTR (address, JavaThread::check_special_condition_for_native_trans)));
283310 __ blr (tmp1);
284311
285- if (!_needs_return_buffer ) {
312+ if (should_save_return_value ) {
286313 out_reg_spiller.generate_fill (_masm, spill_offset);
287314 }
288315
@@ -294,13 +321,13 @@ void DowncallStubGenerator::generate() {
294321 __ block_comment (" { L_reguard" );
295322 __ bind (L_reguard);
296323
297- if (!_needs_return_buffer ) {
324+ if (should_save_return_value ) {
298325 out_reg_spiller.generate_spill (_masm, spill_offset);
299326 }
300327
301328 __ rt_call (CAST_FROM_FN_PTR (address, SharedRuntime::reguard_yellow_pages), tmp1);
302329
303- if (!_needs_return_buffer ) {
330+ if (should_save_return_value ) {
304331 out_reg_spiller.generate_fill (_masm, spill_offset);
305332 }
306333
0 commit comments