< prev index next >

src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp

Print this page


   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 #include "asm/macroAssembler.hpp"
  27 #include "asm/macroAssembler.inline.hpp"
  28 #include "code/debugInfoRec.hpp"
  29 #include "code/icBuffer.hpp"
  30 #include "code/nativeInst.hpp"
  31 #include "code/vtableStubs.hpp"
  32 #include "gc/shared/gcLocker.hpp"

  33 #include "interpreter/interpreter.hpp"
  34 #include "logging/log.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "oops/compiledICHolder.hpp"
  37 #include "runtime/safepointMechanism.hpp"
  38 #include "runtime/sharedRuntime.hpp"
  39 #include "runtime/vframeArray.hpp"
  40 #include "utilities/align.hpp"
  41 #include "vmreg_x86.inline.hpp"
  42 #ifdef COMPILER1
  43 #include "c1/c1_Runtime1.hpp"
  44 #endif
  45 #ifdef COMPILER2
  46 #include "opto/runtime.hpp"
  47 #endif
  48 #include "vm_version_x86.hpp"
  49 
  50 #define __ masm->
  51 
  52 const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;


1286     } else if (in_regs[i].first()->is_XMMRegister()) {
1287       if (in_sig_bt[i] == T_FLOAT) {
1288         int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area;
1289         int offset = slot * VMRegImpl::stack_slot_size;
1290         assert(handle_index <= stack_slots, "overflow");
1291         if (map != NULL) {
1292           __ movflt(Address(rsp, offset), in_regs[i].first()->as_XMMRegister());
1293         } else {
1294           __ movflt(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset));
1295         }
1296       }
1297     } else if (in_regs[i].first()->is_stack()) {
1298       if (in_sig_bt[i] == T_ARRAY && map != NULL) {
1299         int offset_in_older_frame = in_regs[i].first()->reg2stack() + SharedRuntime::out_preserve_stack_slots();
1300         map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + stack_slots));
1301       }
1302     }
1303   }
1304 }
1305 



























































































1306 // Check GCLocker::needs_gc and enter the runtime if it's true.  This
1307 // keeps a new JNI critical region from starting until a GC has been
1308 // forced.  Save down any oops in registers and describe them in an
1309 // OopMap.
1310 static void check_needs_gc_for_critical_native(MacroAssembler* masm,
1311                                                Register thread,
1312                                                int stack_slots,
1313                                                int total_c_args,
1314                                                int total_in_args,
1315                                                int arg_save_area,
1316                                                OopMapSet* oop_maps,
1317                                                VMRegPair* in_regs,
1318                                                BasicType* in_sig_bt) {
1319   __ block_comment("check GCLocker::needs_gc");
1320   Label cont;
1321   __ cmp8(ExternalAddress((address)GCLocker::needs_gc_address()), false);
1322   __ jcc(Assembler::equal, cont);
1323 
1324   // Save down any incoming oops and call into the runtime to halt for a GC
1325 


1821   } else {
1822     __ empty_FPU_stack();
1823   }
1824 #endif /* COMPILER2 */
1825 
1826   // Compute the rbp, offset for any slots used after the jni call
1827 
1828   int lock_slot_rbp_offset = (lock_slot_offset*VMRegImpl::stack_slot_size) - fp_adjustment;
1829 
1830   // We use rdi as a thread pointer because it is callee save and
1831   // if we load it once it is usable thru the entire wrapper
1832   const Register thread = rdi;
1833 
1834   // We use rsi as the oop handle for the receiver/klass
1835   // It is callee save so it survives the call to native
1836 
1837   const Register oop_handle_reg = rsi;
1838 
1839   __ get_thread(thread);
1840 
1841   if (is_critical_native) {
1842     check_needs_gc_for_critical_native(masm, thread, stack_slots, total_c_args, total_in_args,
1843                                        oop_handle_offset, oop_maps, in_regs, in_sig_bt);
1844   }
1845 
1846   //
1847   // We immediately shuffle the arguments so that any vm call we have to
1848   // make from here on out (sync slow path, jvmti, etc.) we will have
1849   // captured the oops from our caller and have a valid oopMap for
1850   // them.
1851 
1852   // -----------------
1853   // The Grand Shuffle
1854   //
1855   // Natives require 1 or 2 extra arguments over the normal ones: the JNIEnv*
1856   // and, if static, the class mirror instead of a receiver.  This pretty much
1857   // guarantees that register layout will not match (and x86 doesn't use reg
1858   // parms though amd does).  Since the native abi doesn't use register args
1859   // and the java conventions does we don't have to worry about collisions.
1860   // All of our moved are reg->stack or stack->stack.
1861   // We ignore the extra arguments during the shuffle and handle them at the
1862   // last moment. The shuffle is described by the two calling convention
1863   // vectors we have in our possession. We simply walk the java vector to
1864   // get the source locations and the c vector to get the destinations.
1865 
1866   int c_arg = is_critical_native ? 0 : (method->is_static() ? 2 : 1 );
1867 
1868   // Record rsp-based slot for receiver on stack for non-static methods
1869   int receiver_offset = -1;
1870 
1871   // This is a trick. We double the stack slots so we can claim
1872   // the oops in the caller's frame. Since we are sure to have
1873   // more args than the caller doubling is enough to make
1874   // sure we can capture all the incoming oop args from the
1875   // caller.
1876   //
1877   OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
1878 





1879   // Mark location of rbp,
1880   // map->set_callee_saved(VMRegImpl::stack2reg( stack_slots - 2), stack_slots * 2, 0, rbp->as_VMReg());
1881 
1882   // We know that we only have args in at most two integer registers (rcx, rdx). So rax, rbx
1883   // Are free to temporaries if we have to do  stack to steck moves.
1884   // All inbound args are referenced based on rbp, and all outbound args via rsp.
1885 
1886   for (int i = 0; i < total_in_args ; i++, c_arg++ ) {
1887     switch (in_sig_bt[i]) {
1888       case T_ARRAY:
1889         if (is_critical_native) {
1890           unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]);





















1891           c_arg++;
1892           break;
1893         }
1894       case T_OBJECT:
1895         assert(!is_critical_native, "no oop arguments");
1896         object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg],
1897                     ((i == 0) && (!is_static)),
1898                     &receiver_offset);
1899         break;
1900       case T_VOID:
1901         break;
1902 
1903       case T_FLOAT:
1904         float_move(masm, in_regs[i], out_regs[c_arg]);
1905           break;
1906 
1907       case T_DOUBLE:
1908         assert( i + 1 < total_in_args &&
1909                 in_sig_bt[i + 1] == T_VOID &&
1910                 out_sig_bt[c_arg+1] == T_VOID, "bad arg list");


2064   // and continue to do SP relative addressing but we instead switch to FP
2065   // relative addressing.
2066 
2067   // Unpack native results.
2068   switch (ret_type) {
2069   case T_BOOLEAN: __ c2bool(rax);            break;
2070   case T_CHAR   : __ andptr(rax, 0xFFFF);    break;
2071   case T_BYTE   : __ sign_extend_byte (rax); break;
2072   case T_SHORT  : __ sign_extend_short(rax); break;
2073   case T_INT    : /* nothing to do */        break;
2074   case T_DOUBLE :
2075   case T_FLOAT  :
2076     // Result is in st0 we'll save as needed
2077     break;
2078   case T_ARRAY:                 // Really a handle
2079   case T_OBJECT:                // Really a handle
2080       break; // can't de-handlize until after safepoint check
2081   case T_VOID: break;
2082   case T_LONG: break;
2083   default       : ShouldNotReachHere();




















2084   }
2085 
2086   // Switch thread to "native transition" state before reading the synchronization state.
2087   // This additional state is necessary because reading and testing the synchronization
2088   // state is not atomic w.r.t. GC, as this scenario demonstrates:
2089   //     Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
2090   //     VM thread changes sync state to synchronizing and suspends threads for GC.
2091   //     Thread A is resumed to finish this native method, but doesn't block here since it
2092   //     didn't see any synchronization is progress, and escapes.
2093   __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans);
2094 
2095   if(os::is_MP()) {
2096     if (UseMembar) {
2097       // Force this write out before the read below
2098       __ membar(Assembler::Membar_mask_bits(
2099            Assembler::LoadLoad | Assembler::LoadStore |
2100            Assembler::StoreLoad | Assembler::StoreStore));
2101     } else {
2102       // Write serialization page so VM thread can do a pseudo remote membar.
2103       // We use the current thread pointer to calculate a thread specific


   1 /*
   2  * Copyright (c) 2003, 2020, 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 #include "asm/macroAssembler.hpp"
  27 #include "asm/macroAssembler.inline.hpp"
  28 #include "code/debugInfoRec.hpp"
  29 #include "code/icBuffer.hpp"
  30 #include "code/nativeInst.hpp"
  31 #include "code/vtableStubs.hpp"
  32 #include "gc/shared/gcLocker.hpp"
  33 #include "gc/shared/collectedHeap.hpp"
  34 #include "interpreter/interpreter.hpp"
  35 #include "logging/log.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "oops/compiledICHolder.hpp"
  38 #include "runtime/safepointMechanism.hpp"
  39 #include "runtime/sharedRuntime.hpp"
  40 #include "runtime/vframeArray.hpp"
  41 #include "utilities/align.hpp"
  42 #include "vmreg_x86.inline.hpp"
  43 #ifdef COMPILER1
  44 #include "c1/c1_Runtime1.hpp"
  45 #endif
  46 #ifdef COMPILER2
  47 #include "opto/runtime.hpp"
  48 #endif
  49 #include "vm_version_x86.hpp"
  50 
  51 #define __ masm->
  52 
  53 const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;


1287     } else if (in_regs[i].first()->is_XMMRegister()) {
1288       if (in_sig_bt[i] == T_FLOAT) {
1289         int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area;
1290         int offset = slot * VMRegImpl::stack_slot_size;
1291         assert(handle_index <= stack_slots, "overflow");
1292         if (map != NULL) {
1293           __ movflt(Address(rsp, offset), in_regs[i].first()->as_XMMRegister());
1294         } else {
1295           __ movflt(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset));
1296         }
1297       }
1298     } else if (in_regs[i].first()->is_stack()) {
1299       if (in_sig_bt[i] == T_ARRAY && map != NULL) {
1300         int offset_in_older_frame = in_regs[i].first()->reg2stack() + SharedRuntime::out_preserve_stack_slots();
1301         map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + stack_slots));
1302       }
1303     }
1304   }
1305 }
1306 
1307 // Registers need to be saved for runtime call
1308 static Register caller_saved_registers[] = {
1309   rcx, rdx, rsi, rdi
1310 };
1311 
1312 // Save caller saved registers except r1 and r2
1313 static void save_registers_except(MacroAssembler* masm, Register r1, Register r2) {
1314   int reg_len = (int)(sizeof(caller_saved_registers) / sizeof(Register));
1315   for (int index = 0; index < reg_len; index ++) {
1316     Register this_reg = caller_saved_registers[index];
1317     if (this_reg != r1 && this_reg != r2) {
1318       __ push(this_reg);
1319     }
1320   }
1321 }
1322 
1323 // Restore caller saved registers except r1 and r2
1324 static void restore_registers_except(MacroAssembler* masm, Register r1, Register r2) {
1325   int reg_len = (int)(sizeof(caller_saved_registers) / sizeof(Register));
1326   for (int index = reg_len - 1; index >= 0; index --) {
1327     Register this_reg = caller_saved_registers[index];
1328     if (this_reg != r1 && this_reg != r2) {
1329       __ pop(this_reg);
1330     }
1331   }
1332 }
1333 
1334 // Pin object, return pinned object or null in rax
1335 static void gen_pin_object(MacroAssembler* masm,
1336                            Register thread, VMRegPair reg) {
1337   __ block_comment("gen_pin_object {");
1338 
1339   Label is_null;
1340   Register tmp_reg = rax;
1341   VMRegPair tmp(tmp_reg->as_VMReg());
1342   if (reg.first()->is_stack()) {
1343     // Load the arg up from the stack
1344     simple_move32(masm, reg, tmp);
1345     reg = tmp;
1346   } else {
1347     __ movl(tmp_reg, reg.first()->as_Register());
1348   }
1349   __ testptr(reg.first()->as_Register(), reg.first()->as_Register());
1350   __ jccb(Assembler::equal, is_null);
1351 
1352   // Save registers that may be used by runtime call
1353   Register arg = reg.first()->is_Register() ? reg.first()->as_Register() : noreg;
1354   save_registers_except(masm, arg, thread);
1355 
1356   __ call_VM_leaf(
1357     CAST_FROM_FN_PTR(address, SharedRuntime::pin_object),
1358     thread, reg.first()->as_Register());
1359 
1360   // Restore saved registers
1361   restore_registers_except(masm, arg, thread);
1362 
1363   __ bind(is_null);
1364   __ block_comment("} gen_pin_object");
1365 }
1366 
1367 // Unpin object
1368 static void gen_unpin_object(MacroAssembler* masm,
1369                              Register thread, VMRegPair reg) {
1370   __ block_comment("gen_unpin_object {");
1371   Label is_null;
1372 
1373   // temp register
1374   __ push(rax);
1375   Register tmp_reg = rax;
1376   VMRegPair tmp(tmp_reg->as_VMReg());
1377 
1378   simple_move32(masm, reg, tmp);
1379 
1380   __ testptr(rax, rax);
1381   __ jccb(Assembler::equal, is_null);
1382 
1383   // Save registers that may be used by runtime call
1384   Register arg = reg.first()->is_Register() ? reg.first()->as_Register() : noreg;
1385   save_registers_except(masm, arg, thread);
1386 
1387   __ call_VM_leaf(
1388     CAST_FROM_FN_PTR(address, SharedRuntime::unpin_object),
1389     thread, rax);
1390 
1391   // Restore saved registers
1392   restore_registers_except(masm, arg, thread);
1393   __ bind(is_null);
1394   __ pop(rax);
1395   __ block_comment("} gen_unpin_object");
1396 }
1397 
1398 // Check GCLocker::needs_gc and enter the runtime if it's true.  This
1399 // keeps a new JNI critical region from starting until a GC has been
1400 // forced.  Save down any oops in registers and describe them in an
1401 // OopMap.
1402 static void check_needs_gc_for_critical_native(MacroAssembler* masm,
1403                                                Register thread,
1404                                                int stack_slots,
1405                                                int total_c_args,
1406                                                int total_in_args,
1407                                                int arg_save_area,
1408                                                OopMapSet* oop_maps,
1409                                                VMRegPair* in_regs,
1410                                                BasicType* in_sig_bt) {
1411   __ block_comment("check GCLocker::needs_gc");
1412   Label cont;
1413   __ cmp8(ExternalAddress((address)GCLocker::needs_gc_address()), false);
1414   __ jcc(Assembler::equal, cont);
1415 
1416   // Save down any incoming oops and call into the runtime to halt for a GC
1417 


1913   } else {
1914     __ empty_FPU_stack();
1915   }
1916 #endif /* COMPILER2 */
1917 
1918   // Compute the rbp, offset for any slots used after the jni call
1919 
1920   int lock_slot_rbp_offset = (lock_slot_offset*VMRegImpl::stack_slot_size) - fp_adjustment;
1921 
1922   // We use rdi as a thread pointer because it is callee save and
1923   // if we load it once it is usable thru the entire wrapper
1924   const Register thread = rdi;
1925 
1926   // We use rsi as the oop handle for the receiver/klass
1927   // It is callee save so it survives the call to native
1928 
1929   const Register oop_handle_reg = rsi;
1930 
1931   __ get_thread(thread);
1932 
1933   if (is_critical_native && !Universe::heap()->supports_object_pinning()) {
1934     check_needs_gc_for_critical_native(masm, thread, stack_slots, total_c_args, total_in_args,
1935                                        oop_handle_offset, oop_maps, in_regs, in_sig_bt);
1936   }
1937 
1938   //
1939   // We immediately shuffle the arguments so that any vm call we have to
1940   // make from here on out (sync slow path, jvmti, etc.) we will have
1941   // captured the oops from our caller and have a valid oopMap for
1942   // them.
1943 
1944   // -----------------
1945   // The Grand Shuffle
1946   //
1947   // Natives require 1 or 2 extra arguments over the normal ones: the JNIEnv*
1948   // and, if static, the class mirror instead of a receiver.  This pretty much
1949   // guarantees that register layout will not match (and x86 doesn't use reg
1950   // parms though amd does).  Since the native abi doesn't use register args
1951   // and the java conventions does we don't have to worry about collisions.
1952   // All of our moved are reg->stack or stack->stack.
1953   // We ignore the extra arguments during the shuffle and handle them at the
1954   // last moment. The shuffle is described by the two calling convention
1955   // vectors we have in our possession. We simply walk the java vector to
1956   // get the source locations and the c vector to get the destinations.
1957 
1958   int c_arg = is_critical_native ? 0 : (method->is_static() ? 2 : 1 );
1959 
1960   // Record rsp-based slot for receiver on stack for non-static methods
1961   int receiver_offset = -1;
1962 
1963   // This is a trick. We double the stack slots so we can claim
1964   // the oops in the caller's frame. Since we are sure to have
1965   // more args than the caller doubling is enough to make
1966   // sure we can capture all the incoming oop args from the
1967   // caller.
1968   //
1969   OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
1970 
1971   // Inbound arguments that need to be pinned for critical natives
1972   GrowableArray<int> pinned_args(total_in_args);
1973   // Current stack slot for storing register based array argument
1974   int pinned_slot = oop_handle_offset;
1975 
1976   // Mark location of rbp,
1977   // map->set_callee_saved(VMRegImpl::stack2reg( stack_slots - 2), stack_slots * 2, 0, rbp->as_VMReg());
1978 
1979   // We know that we only have args in at most two integer registers (rcx, rdx). So rax, rbx
1980   // Are free to temporaries if we have to do  stack to steck moves.
1981   // All inbound args are referenced based on rbp, and all outbound args via rsp.
1982 
1983   for (int i = 0; i < total_in_args ; i++, c_arg++ ) {
1984     switch (in_sig_bt[i]) {
1985       case T_ARRAY:
1986         if (is_critical_native) {
1987           VMRegPair in_arg = in_regs[i];
1988           if (Universe::heap()->supports_object_pinning()) {
1989             // gen_pin_object handles save and restore
1990             // of any clobbered registers
1991             gen_pin_object(masm, thread, in_arg);
1992             pinned_args.append(i);
1993 
1994             // rax has pinned array
1995             VMRegPair result_reg(rax->as_VMReg());
1996             if (!in_arg.first()->is_stack()) {
1997               assert(pinned_slot <= stack_slots, "overflow");
1998               simple_move32(masm, result_reg, VMRegImpl::stack2reg(pinned_slot));
1999               pinned_slot += VMRegImpl::slots_per_word;
2000             } else {
2001               // Write back pinned value, it will be used to unpin this argument
2002               __ movptr(Address(rbp, reg2offset_in(in_arg.first())), result_reg.first()->as_Register());
2003             }
2004             // We have the array in register, use it
2005             in_arg = result_reg;
2006           }
2007 
2008           unpack_array_argument(masm, in_arg, in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]);
2009           c_arg++;
2010           break;
2011         }
2012       case T_OBJECT:
2013         assert(!is_critical_native, "no oop arguments");
2014         object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg],
2015                     ((i == 0) && (!is_static)),
2016                     &receiver_offset);
2017         break;
2018       case T_VOID:
2019         break;
2020 
2021       case T_FLOAT:
2022         float_move(masm, in_regs[i], out_regs[c_arg]);
2023           break;
2024 
2025       case T_DOUBLE:
2026         assert( i + 1 < total_in_args &&
2027                 in_sig_bt[i + 1] == T_VOID &&
2028                 out_sig_bt[c_arg+1] == T_VOID, "bad arg list");


2182   // and continue to do SP relative addressing but we instead switch to FP
2183   // relative addressing.
2184 
2185   // Unpack native results.
2186   switch (ret_type) {
2187   case T_BOOLEAN: __ c2bool(rax);            break;
2188   case T_CHAR   : __ andptr(rax, 0xFFFF);    break;
2189   case T_BYTE   : __ sign_extend_byte (rax); break;
2190   case T_SHORT  : __ sign_extend_short(rax); break;
2191   case T_INT    : /* nothing to do */        break;
2192   case T_DOUBLE :
2193   case T_FLOAT  :
2194     // Result is in st0 we'll save as needed
2195     break;
2196   case T_ARRAY:                 // Really a handle
2197   case T_OBJECT:                // Really a handle
2198       break; // can't de-handlize until after safepoint check
2199   case T_VOID: break;
2200   case T_LONG: break;
2201   default       : ShouldNotReachHere();
2202   }
2203 
2204   // unpin pinned arguments
2205   pinned_slot = oop_handle_offset;
2206   if (pinned_args.length() > 0) {
2207     // save return value that may be overwritten otherwise.
2208     save_native_result(masm, ret_type, stack_slots);
2209     for (int index = 0; index < pinned_args.length(); index ++) {
2210       int i = pinned_args.at(index);
2211       assert(pinned_slot <= stack_slots, "overflow");
2212       if (!in_regs[i].first()->is_stack()) {
2213         int offset = pinned_slot * VMRegImpl::stack_slot_size;
2214         __ movl(in_regs[i].first()->as_Register(), Address(rsp, offset));
2215         pinned_slot += VMRegImpl::slots_per_word;
2216       }
2217       // gen_pin_object handles save and restore
2218       // of any other clobbered registers
2219       gen_unpin_object(masm, thread, in_regs[i]);
2220     }
2221     restore_native_result(masm, ret_type, stack_slots);
2222   }
2223 
2224   // Switch thread to "native transition" state before reading the synchronization state.
2225   // This additional state is necessary because reading and testing the synchronization
2226   // state is not atomic w.r.t. GC, as this scenario demonstrates:
2227   //     Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
2228   //     VM thread changes sync state to synchronizing and suspends threads for GC.
2229   //     Thread A is resumed to finish this native method, but doesn't block here since it
2230   //     didn't see any synchronization is progress, and escapes.
2231   __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans);
2232 
2233   if(os::is_MP()) {
2234     if (UseMembar) {
2235       // Force this write out before the read below
2236       __ membar(Assembler::Membar_mask_bits(
2237            Assembler::LoadLoad | Assembler::LoadStore |
2238            Assembler::StoreLoad | Assembler::StoreStore));
2239     } else {
2240       // Write serialization page so VM thread can do a pseudo remote membar.
2241       // We use the current thread pointer to calculate a thread specific


< prev index next >