< prev index next >

src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp

Print this page


   1 /*
   2  * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #ifndef _WINDOWS
  27 #include "alloca.h"
  28 #endif
  29 #include "asm/macroAssembler.hpp"
  30 #include "asm/macroAssembler.inline.hpp"
  31 #include "code/debugInfoRec.hpp"
  32 #include "code/icBuffer.hpp"
  33 #include "code/nativeInst.hpp"
  34 #include "code/vtableStubs.hpp"
  35 #include "gc/shared/gcLocker.hpp"

  36 #include "interpreter/interpreter.hpp"
  37 #include "logging/log.hpp"
  38 #include "memory/resourceArea.hpp"
  39 #include "oops/compiledICHolder.hpp"
  40 #include "runtime/safepointMechanism.hpp"
  41 #include "runtime/sharedRuntime.hpp"
  42 #include "runtime/vframeArray.hpp"
  43 #include "utilities/align.hpp"
  44 #include "utilities/formatBuffer.hpp"
  45 #include "vm_version_x86.hpp"
  46 #include "vmreg_x86.inline.hpp"
  47 #ifdef COMPILER1
  48 #include "c1/c1_Runtime1.hpp"
  49 #endif
  50 #ifdef COMPILER2
  51 #include "opto/runtime.hpp"
  52 #endif
  53 #if INCLUDE_JVMCI
  54 #include "jvmci/jvmciJavaClasses.hpp"
  55 #endif


1417     } else if (in_regs[i].first()->is_XMMRegister()) {
1418       if (in_sig_bt[i] == T_FLOAT) {
1419         int offset = slot * VMRegImpl::stack_slot_size;
1420         slot++;
1421         assert(slot <= stack_slots, "overflow");
1422         if (map != NULL) {
1423           __ movflt(Address(rsp, offset), in_regs[i].first()->as_XMMRegister());
1424         } else {
1425           __ movflt(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset));
1426         }
1427       }
1428     } else if (in_regs[i].first()->is_stack()) {
1429       if (in_sig_bt[i] == T_ARRAY && map != NULL) {
1430         int offset_in_older_frame = in_regs[i].first()->reg2stack() + SharedRuntime::out_preserve_stack_slots();
1431         map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + stack_slots));
1432       }
1433     }
1434   }
1435 }
1436 






























































































1437 
1438 // Check GCLocker::needs_gc and enter the runtime if it's true.  This
1439 // keeps a new JNI critical region from starting until a GC has been
1440 // forced.  Save down any oops in registers and describe them in an
1441 // OopMap.
1442 static void check_needs_gc_for_critical_native(MacroAssembler* masm,
1443                                                int stack_slots,
1444                                                int total_c_args,
1445                                                int total_in_args,
1446                                                int arg_save_area,
1447                                                OopMapSet* oop_maps,
1448                                                VMRegPair* in_regs,
1449                                                BasicType* in_sig_bt) {
1450   __ block_comment("check GCLocker::needs_gc");
1451   Label cont;
1452   __ cmp8(ExternalAddress((address)GCLocker::needs_gc_address()), false);
1453   __ jcc(Assembler::equal, cont);
1454 
1455   // Save down any incoming oops and call into the runtime to halt for a GC
1456 


2112     }
2113 
2114 #ifdef ASSERT
2115     {
2116       Label L;
2117       __ mov(rax, rsp);
2118       __ andptr(rax, -16); // must be 16 byte boundary (see amd64 ABI)
2119       __ cmpptr(rax, rsp);
2120       __ jcc(Assembler::equal, L);
2121       __ stop("improperly aligned stack");
2122       __ bind(L);
2123     }
2124 #endif /* ASSERT */
2125 
2126 
2127   // We use r14 as the oop handle for the receiver/klass
2128   // It is callee save so it survives the call to native
2129 
2130   const Register oop_handle_reg = r14;
2131 
2132   if (is_critical_native) {
2133     check_needs_gc_for_critical_native(masm, stack_slots, total_c_args, total_in_args,
2134                                        oop_handle_offset, oop_maps, in_regs, in_sig_bt);
2135   }
2136 
2137   //
2138   // We immediately shuffle the arguments so that any vm call we have to
2139   // make from here on out (sync slow path, jvmti, etc.) we will have
2140   // captured the oops from our caller and have a valid oopMap for
2141   // them.
2142 
2143   // -----------------
2144   // The Grand Shuffle
2145 
2146   // The Java calling convention is either equal (linux) or denser (win64) than the
2147   // c calling convention. However the because of the jni_env argument the c calling
2148   // convention always has at least one more (and two for static) arguments than Java.
2149   // Therefore if we move the args from java -> c backwards then we will never have
2150   // a register->register conflict and we don't have to build a dependency graph
2151   // and figure out how to break any cycles.
2152   //


2169   // All inbound args are referenced based on rbp and all outbound args via rsp.
2170 
2171 
2172 #ifdef ASSERT
2173   bool reg_destroyed[RegisterImpl::number_of_registers];
2174   bool freg_destroyed[XMMRegisterImpl::number_of_registers];
2175   for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) {
2176     reg_destroyed[r] = false;
2177   }
2178   for ( int f = 0 ; f < XMMRegisterImpl::number_of_registers ; f++ ) {
2179     freg_destroyed[f] = false;
2180   }
2181 
2182 #endif /* ASSERT */
2183 
2184   // This may iterate in two different directions depending on the
2185   // kind of native it is.  The reason is that for regular JNI natives
2186   // the incoming and outgoing registers are offset upwards and for
2187   // critical natives they are offset down.
2188   GrowableArray<int> arg_order(2 * total_in_args);





2189   VMRegPair tmp_vmreg;
2190   tmp_vmreg.set2(rbx->as_VMReg());
2191 
2192   if (!is_critical_native) {
2193     for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) {
2194       arg_order.push(i);
2195       arg_order.push(c_arg);
2196     }
2197   } else {
2198     // Compute a valid move order, using tmp_vmreg to break any cycles
2199     ComputeMoveOrder cmo(total_in_args, in_regs, total_c_args, out_regs, in_sig_bt, arg_order, tmp_vmreg);
2200   }
2201 
2202   int temploc = -1;
2203   for (int ai = 0; ai < arg_order.length(); ai += 2) {
2204     int i = arg_order.at(ai);
2205     int c_arg = arg_order.at(ai + 1);
2206     __ block_comment(err_msg("move %d -> %d", i, c_arg));
2207     if (c_arg == -1) {
2208       assert(is_critical_native, "should only be required for critical natives");


2216       // Read from the temporary location
2217       assert(temploc != -1, "must be valid");
2218       i = temploc;
2219       temploc = -1;
2220     }
2221 #ifdef ASSERT
2222     if (in_regs[i].first()->is_Register()) {
2223       assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "destroyed reg!");
2224     } else if (in_regs[i].first()->is_XMMRegister()) {
2225       assert(!freg_destroyed[in_regs[i].first()->as_XMMRegister()->encoding()], "destroyed reg!");
2226     }
2227     if (out_regs[c_arg].first()->is_Register()) {
2228       reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true;
2229     } else if (out_regs[c_arg].first()->is_XMMRegister()) {
2230       freg_destroyed[out_regs[c_arg].first()->as_XMMRegister()->encoding()] = true;
2231     }
2232 #endif /* ASSERT */
2233     switch (in_sig_bt[i]) {
2234       case T_ARRAY:
2235         if (is_critical_native) {






2236           unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]);
2237           c_arg++;
2238 #ifdef ASSERT
2239           if (out_regs[c_arg].first()->is_Register()) {
2240             reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true;
2241           } else if (out_regs[c_arg].first()->is_XMMRegister()) {
2242             freg_destroyed[out_regs[c_arg].first()->as_XMMRegister()->encoding()] = true;
2243           }
2244 #endif
2245           break;
2246         }
2247       case T_OBJECT:
2248         assert(!is_critical_native, "no oop arguments");
2249         object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg],
2250                     ((i == 0) && (!is_static)),
2251                     &receiver_offset);
2252         break;
2253       case T_VOID:
2254         break;
2255 


2430   // Verify or restore cpu control state after JNI call
2431   __ restore_cpu_control_state_after_jni();
2432 
2433   // Unpack native results.
2434   switch (ret_type) {
2435   case T_BOOLEAN: __ c2bool(rax);            break;
2436   case T_CHAR   : __ movzwl(rax, rax);      break;
2437   case T_BYTE   : __ sign_extend_byte (rax); break;
2438   case T_SHORT  : __ sign_extend_short(rax); break;
2439   case T_INT    : /* nothing to do */        break;
2440   case T_DOUBLE :
2441   case T_FLOAT  :
2442     // Result is in xmm0 we'll save as needed
2443     break;
2444   case T_ARRAY:                 // Really a handle
2445   case T_OBJECT:                // Really a handle
2446       break; // can't de-handlize until after safepoint check
2447   case T_VOID: break;
2448   case T_LONG: break;
2449   default       : ShouldNotReachHere();













2450   }
2451 
2452   // Switch thread to "native transition" state before reading the synchronization state.
2453   // This additional state is necessary because reading and testing the synchronization
2454   // state is not atomic w.r.t. GC, as this scenario demonstrates:
2455   //     Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
2456   //     VM thread changes sync state to synchronizing and suspends threads for GC.
2457   //     Thread A is resumed to finish this native method, but doesn't block here since it
2458   //     didn't see any synchronization is progress, and escapes.
2459   __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native_trans);
2460 
2461   if(os::is_MP()) {
2462     if (UseMembar) {
2463       // Force this write out before the read below
2464       __ membar(Assembler::Membar_mask_bits(
2465            Assembler::LoadLoad | Assembler::LoadStore |
2466            Assembler::StoreLoad | Assembler::StoreStore));
2467     } else {
2468       // Write serialization page so VM thread can do a pseudo remote membar.
2469       // We use the current thread pointer to calculate a thread specific


   1 /*
   2  * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #ifndef _WINDOWS
  27 #include "alloca.h"
  28 #endif
  29 #include "asm/macroAssembler.hpp"
  30 #include "asm/macroAssembler.inline.hpp"
  31 #include "code/debugInfoRec.hpp"
  32 #include "code/icBuffer.hpp"
  33 #include "code/nativeInst.hpp"
  34 #include "code/vtableStubs.hpp"
  35 #include "gc/shared/gcLocker.hpp"
  36 #include "gc/shared/collectedHeap.hpp"
  37 #include "interpreter/interpreter.hpp"
  38 #include "logging/log.hpp"
  39 #include "memory/resourceArea.hpp"
  40 #include "oops/compiledICHolder.hpp"
  41 #include "runtime/safepointMechanism.hpp"
  42 #include "runtime/sharedRuntime.hpp"
  43 #include "runtime/vframeArray.hpp"
  44 #include "utilities/align.hpp"
  45 #include "utilities/formatBuffer.hpp"
  46 #include "vm_version_x86.hpp"
  47 #include "vmreg_x86.inline.hpp"
  48 #ifdef COMPILER1
  49 #include "c1/c1_Runtime1.hpp"
  50 #endif
  51 #ifdef COMPILER2
  52 #include "opto/runtime.hpp"
  53 #endif
  54 #if INCLUDE_JVMCI
  55 #include "jvmci/jvmciJavaClasses.hpp"
  56 #endif


1418     } else if (in_regs[i].first()->is_XMMRegister()) {
1419       if (in_sig_bt[i] == T_FLOAT) {
1420         int offset = slot * VMRegImpl::stack_slot_size;
1421         slot++;
1422         assert(slot <= stack_slots, "overflow");
1423         if (map != NULL) {
1424           __ movflt(Address(rsp, offset), in_regs[i].first()->as_XMMRegister());
1425         } else {
1426           __ movflt(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset));
1427         }
1428       }
1429     } else if (in_regs[i].first()->is_stack()) {
1430       if (in_sig_bt[i] == T_ARRAY && map != NULL) {
1431         int offset_in_older_frame = in_regs[i].first()->reg2stack() + SharedRuntime::out_preserve_stack_slots();
1432         map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + stack_slots));
1433       }
1434     }
1435   }
1436 }
1437 
1438 // Pin incoming array argument of java critical method
1439 static void pin_critical_native_array(MacroAssembler* masm,
1440                                       VMRegPair reg,
1441                                       int& pinned_slot) {
1442   __ block_comment("pin_critical_native_array {");
1443   Register tmp_reg = rax;
1444 
1445   Label is_null;
1446   VMRegPair tmp;
1447   VMRegPair in_reg = reg;
1448   bool on_stack = false;
1449 
1450   tmp.set_ptr(tmp_reg->as_VMReg());
1451   if (reg.first()->is_stack()) {
1452     // Load the arg up from the stack
1453     move_ptr(masm, reg, tmp);
1454     reg = tmp;
1455     on_stack = true;
1456   } else {
1457     __ movptr(rax, reg.first()->as_Register());
1458   }
1459   __ testptr(reg.first()->as_Register(), reg.first()->as_Register());
1460   __ jccb(Assembler::equal, is_null);
1461 
1462   __ push(c_rarg0);
1463   __ push(c_rarg1);
1464   __ push(c_rarg2);
1465   __ push(c_rarg3);
1466 #ifdef _WIN64
1467   // caller-saved registers on Windows
1468   __ push(r10);
1469   __ push(r11);
1470 #else
1471   __ push(c_rarg4);
1472   __ push(c_rarg5);
1473 #endif
1474 
1475   if (reg.first()->as_Register() != c_rarg1) {
1476     __ movptr(c_rarg1, reg.first()->as_Register());
1477   }
1478   __ movptr(c_rarg0, r15_thread);
1479   __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::pin_object)));
1480 
1481 #ifdef _WIN64
1482   __ pop(r11);
1483   __ pop(r10);
1484 #else
1485   __ pop(c_rarg5);
1486   __ pop(c_rarg4);
1487 #endif
1488   __ pop(c_rarg3);
1489   __ pop(c_rarg2);
1490   __ pop(c_rarg1);
1491   __ pop(c_rarg0);
1492 
1493   if (on_stack) {
1494     __ movptr(Address(rbp, reg2offset_in(in_reg.first())), rax);
1495     __ bind(is_null);
1496   } else {
1497     __ movptr(reg.first()->as_Register(), rax);
1498 
1499     // save on stack for unpinning later
1500     __ bind(is_null);
1501     assert(reg.first()->is_Register(), "Must be a register");
1502     int offset = pinned_slot * VMRegImpl::stack_slot_size;
1503     pinned_slot += VMRegImpl::slots_per_word;
1504     __ movq(Address(rsp, offset), rax);
1505   }
1506   __ block_comment("} pin_critical_native_array");
1507 }
1508 
1509 // Unpin array argument of java critical method
1510 static void unpin_critical_native_array(MacroAssembler* masm,
1511                                         VMRegPair reg,
1512                                         int& pinned_slot) {
1513   __ block_comment("unpin_critical_native_array {");
1514   Label is_null;
1515 
1516   if (reg.first()->is_stack()) {
1517     __ movptr(c_rarg1, Address(rbp, reg2offset_in(reg.first())));
1518   } else {
1519     int offset = pinned_slot * VMRegImpl::stack_slot_size;
1520     pinned_slot += VMRegImpl::slots_per_word;
1521     __ movq(c_rarg1, Address(rsp, offset));
1522   }
1523   __ testptr(c_rarg1, c_rarg1);
1524   __ jccb(Assembler::equal, is_null);
1525 
1526   __ movptr(c_rarg0, r15_thread);
1527   __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::unpin_object)));
1528 
1529   __ bind(is_null);
1530   __ block_comment("} unpin_critical_native_array");
1531 }
1532 
1533 // Check GCLocker::needs_gc and enter the runtime if it's true.  This
1534 // keeps a new JNI critical region from starting until a GC has been
1535 // forced.  Save down any oops in registers and describe them in an
1536 // OopMap.
1537 static void check_needs_gc_for_critical_native(MacroAssembler* masm,
1538                                                int stack_slots,
1539                                                int total_c_args,
1540                                                int total_in_args,
1541                                                int arg_save_area,
1542                                                OopMapSet* oop_maps,
1543                                                VMRegPair* in_regs,
1544                                                BasicType* in_sig_bt) {
1545   __ block_comment("check GCLocker::needs_gc");
1546   Label cont;
1547   __ cmp8(ExternalAddress((address)GCLocker::needs_gc_address()), false);
1548   __ jcc(Assembler::equal, cont);
1549 
1550   // Save down any incoming oops and call into the runtime to halt for a GC
1551 


2207     }
2208 
2209 #ifdef ASSERT
2210     {
2211       Label L;
2212       __ mov(rax, rsp);
2213       __ andptr(rax, -16); // must be 16 byte boundary (see amd64 ABI)
2214       __ cmpptr(rax, rsp);
2215       __ jcc(Assembler::equal, L);
2216       __ stop("improperly aligned stack");
2217       __ bind(L);
2218     }
2219 #endif /* ASSERT */
2220 
2221 
2222   // We use r14 as the oop handle for the receiver/klass
2223   // It is callee save so it survives the call to native
2224 
2225   const Register oop_handle_reg = r14;
2226 
2227   if (is_critical_native && !Universe::heap()->supports_object_pinning()) {
2228     check_needs_gc_for_critical_native(masm, stack_slots, total_c_args, total_in_args,
2229                                        oop_handle_offset, oop_maps, in_regs, in_sig_bt);
2230   }
2231 
2232   //
2233   // We immediately shuffle the arguments so that any vm call we have to
2234   // make from here on out (sync slow path, jvmti, etc.) we will have
2235   // captured the oops from our caller and have a valid oopMap for
2236   // them.
2237 
2238   // -----------------
2239   // The Grand Shuffle
2240 
2241   // The Java calling convention is either equal (linux) or denser (win64) than the
2242   // c calling convention. However the because of the jni_env argument the c calling
2243   // convention always has at least one more (and two for static) arguments than Java.
2244   // Therefore if we move the args from java -> c backwards then we will never have
2245   // a register->register conflict and we don't have to build a dependency graph
2246   // and figure out how to break any cycles.
2247   //


2264   // All inbound args are referenced based on rbp and all outbound args via rsp.
2265 
2266 
2267 #ifdef ASSERT
2268   bool reg_destroyed[RegisterImpl::number_of_registers];
2269   bool freg_destroyed[XMMRegisterImpl::number_of_registers];
2270   for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) {
2271     reg_destroyed[r] = false;
2272   }
2273   for ( int f = 0 ; f < XMMRegisterImpl::number_of_registers ; f++ ) {
2274     freg_destroyed[f] = false;
2275   }
2276 
2277 #endif /* ASSERT */
2278 
2279   // This may iterate in two different directions depending on the
2280   // kind of native it is.  The reason is that for regular JNI natives
2281   // the incoming and outgoing registers are offset upwards and for
2282   // critical natives they are offset down.
2283   GrowableArray<int> arg_order(2 * total_in_args);
2284   // Inbound arguments that need to be pinned for critical natives
2285   GrowableArray<int> pinned_args(total_in_args);
2286   // Current stack slot for storing register based array argument
2287   int pinned_slot = oop_handle_offset;
2288 
2289   VMRegPair tmp_vmreg;
2290   tmp_vmreg.set2(rbx->as_VMReg());
2291 
2292   if (!is_critical_native) {
2293     for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) {
2294       arg_order.push(i);
2295       arg_order.push(c_arg);
2296     }
2297   } else {
2298     // Compute a valid move order, using tmp_vmreg to break any cycles
2299     ComputeMoveOrder cmo(total_in_args, in_regs, total_c_args, out_regs, in_sig_bt, arg_order, tmp_vmreg);
2300   }
2301 
2302   int temploc = -1;
2303   for (int ai = 0; ai < arg_order.length(); ai += 2) {
2304     int i = arg_order.at(ai);
2305     int c_arg = arg_order.at(ai + 1);
2306     __ block_comment(err_msg("move %d -> %d", i, c_arg));
2307     if (c_arg == -1) {
2308       assert(is_critical_native, "should only be required for critical natives");


2316       // Read from the temporary location
2317       assert(temploc != -1, "must be valid");
2318       i = temploc;
2319       temploc = -1;
2320     }
2321 #ifdef ASSERT
2322     if (in_regs[i].first()->is_Register()) {
2323       assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "destroyed reg!");
2324     } else if (in_regs[i].first()->is_XMMRegister()) {
2325       assert(!freg_destroyed[in_regs[i].first()->as_XMMRegister()->encoding()], "destroyed reg!");
2326     }
2327     if (out_regs[c_arg].first()->is_Register()) {
2328       reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true;
2329     } else if (out_regs[c_arg].first()->is_XMMRegister()) {
2330       freg_destroyed[out_regs[c_arg].first()->as_XMMRegister()->encoding()] = true;
2331     }
2332 #endif /* ASSERT */
2333     switch (in_sig_bt[i]) {
2334       case T_ARRAY:
2335         if (is_critical_native) {
2336           // pin before unpack
2337           if (Universe::heap()->supports_object_pinning()) {
2338             assert(pinned_slot <= stack_slots, "overflow");
2339             pin_critical_native_array(masm, in_regs[i], pinned_slot);
2340             pinned_args.append(i);
2341           }
2342           unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]);
2343           c_arg++;
2344 #ifdef ASSERT
2345           if (out_regs[c_arg].first()->is_Register()) {
2346             reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true;
2347           } else if (out_regs[c_arg].first()->is_XMMRegister()) {
2348             freg_destroyed[out_regs[c_arg].first()->as_XMMRegister()->encoding()] = true;
2349           }
2350 #endif
2351           break;
2352         }
2353       case T_OBJECT:
2354         assert(!is_critical_native, "no oop arguments");
2355         object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg],
2356                     ((i == 0) && (!is_static)),
2357                     &receiver_offset);
2358         break;
2359       case T_VOID:
2360         break;
2361 


2536   // Verify or restore cpu control state after JNI call
2537   __ restore_cpu_control_state_after_jni();
2538 
2539   // Unpack native results.
2540   switch (ret_type) {
2541   case T_BOOLEAN: __ c2bool(rax);            break;
2542   case T_CHAR   : __ movzwl(rax, rax);      break;
2543   case T_BYTE   : __ sign_extend_byte (rax); break;
2544   case T_SHORT  : __ sign_extend_short(rax); break;
2545   case T_INT    : /* nothing to do */        break;
2546   case T_DOUBLE :
2547   case T_FLOAT  :
2548     // Result is in xmm0 we'll save as needed
2549     break;
2550   case T_ARRAY:                 // Really a handle
2551   case T_OBJECT:                // Really a handle
2552       break; // can't de-handlize until after safepoint check
2553   case T_VOID: break;
2554   case T_LONG: break;
2555   default       : ShouldNotReachHere();
2556   }
2557 
2558   // unpin pinned arguments
2559   pinned_slot = oop_handle_offset;
2560   if (pinned_args.length() > 0) {
2561     // save return value that may be overwritten otherwise.
2562     save_native_result(masm, ret_type, stack_slots);
2563     for (int index = 0; index < pinned_args.length(); index ++) {
2564       int i = pinned_args.at(index);
2565       assert(pinned_slot <= stack_slots, "overflow");
2566       unpin_critical_native_array(masm, in_regs[i], pinned_slot);
2567     }
2568     restore_native_result(masm, ret_type, stack_slots);
2569   }
2570 
2571   // Switch thread to "native transition" state before reading the synchronization state.
2572   // This additional state is necessary because reading and testing the synchronization
2573   // state is not atomic w.r.t. GC, as this scenario demonstrates:
2574   //     Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
2575   //     VM thread changes sync state to synchronizing and suspends threads for GC.
2576   //     Thread A is resumed to finish this native method, but doesn't block here since it
2577   //     didn't see any synchronization is progress, and escapes.
2578   __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native_trans);
2579 
2580   if(os::is_MP()) {
2581     if (UseMembar) {
2582       // Force this write out before the read below
2583       __ membar(Assembler::Membar_mask_bits(
2584            Assembler::LoadLoad | Assembler::LoadStore |
2585            Assembler::StoreLoad | Assembler::StoreStore));
2586     } else {
2587       // Write serialization page so VM thread can do a pseudo remote membar.
2588       // We use the current thread pointer to calculate a thread specific


< prev index next >