hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
changeset 363 99d43e8a76ad
parent 1 489c9b5090e2
child 591 04d2e26e6d69
equal deleted inserted replaced
362:00cf4bffd828 363:99d43e8a76ad
  1878                                             oop_maps);
  1878                                             oop_maps);
  1879   return nm;
  1879   return nm;
  1880 
  1880 
  1881 }
  1881 }
  1882 
  1882 
       
  1883 #ifdef HAVE_DTRACE_H
       
  1884 // ---------------------------------------------------------------------------
       
  1885 // Generate a dtrace nmethod for a given signature.  The method takes arguments
       
  1886 // in the Java compiled code convention, marshals them to the native
       
  1887 // abi and then leaves nops at the position you would expect to call a native
       
  1888 // function. When the probe is enabled the nops are replaced with a trap
       
  1889 // instruction that dtrace inserts and the trace will cause a notification
       
  1890 // to dtrace.
       
  1891 //
       
  1892 // The probes are only able to take primitive types and java/lang/String as
       
  1893 // arguments.  No other java types are allowed. Strings are converted to utf8
       
  1894 // strings so that from dtrace point of view java strings are converted to C
       
  1895 // strings. There is an arbitrary fixed limit on the total space that a method
       
  1896 // can use for converting the strings. (256 chars per string in the signature).
       
  1897 // So any java string larger then this is truncated.
       
  1898 
       
  1899 nmethod *SharedRuntime::generate_dtrace_nmethod(
       
  1900     MacroAssembler *masm, methodHandle method) {
       
  1901 
       
  1902   // generate_dtrace_nmethod is guarded by a mutex so we are sure to
       
  1903   // be single threaded in this method.
       
  1904   assert(AdapterHandlerLibrary_lock->owned_by_self(), "must be");
       
  1905 
       
  1906   // Fill in the signature array, for the calling-convention call.
       
  1907   int total_args_passed = method->size_of_parameters();
       
  1908 
       
  1909   BasicType* in_sig_bt  = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
       
  1910   VMRegPair  *in_regs   = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
       
  1911 
       
  1912   // The signature we are going to use for the trap that dtrace will see
       
  1913   // java/lang/String is converted. We drop "this" and any other object
       
  1914   // is converted to NULL.  (A one-slot java/lang/Long object reference
       
  1915   // is converted to a two-slot long, which is why we double the allocation).
       
  1916   BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed * 2);
       
  1917   VMRegPair* out_regs   = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed * 2);
       
  1918 
       
  1919   int i=0;
       
  1920   int total_strings = 0;
       
  1921   int first_arg_to_pass = 0;
       
  1922   int total_c_args = 0;
       
  1923   int box_offset = java_lang_boxing_object::value_offset_in_bytes();
       
  1924 
       
  1925   if( !method->is_static() ) {  // Pass in receiver first
       
  1926     in_sig_bt[i++] = T_OBJECT;
       
  1927     first_arg_to_pass = 1;
       
  1928   }
       
  1929 
       
  1930   // We need to convert the java args to where a native (non-jni) function
       
  1931   // would expect them. To figure out where they go we convert the java
       
  1932   // signature to a C signature.
       
  1933 
       
  1934   SignatureStream ss(method->signature());
       
  1935   for ( ; !ss.at_return_type(); ss.next()) {
       
  1936     BasicType bt = ss.type();
       
  1937     in_sig_bt[i++] = bt;  // Collect remaining bits of signature
       
  1938     out_sig_bt[total_c_args++] = bt;
       
  1939     if( bt == T_OBJECT) {
       
  1940       symbolOop s = ss.as_symbol_or_null();
       
  1941       if (s == vmSymbols::java_lang_String()) {
       
  1942         total_strings++;
       
  1943         out_sig_bt[total_c_args-1] = T_ADDRESS;
       
  1944       } else if (s == vmSymbols::java_lang_Boolean() ||
       
  1945                  s == vmSymbols::java_lang_Character() ||
       
  1946                  s == vmSymbols::java_lang_Byte() ||
       
  1947                  s == vmSymbols::java_lang_Short() ||
       
  1948                  s == vmSymbols::java_lang_Integer() ||
       
  1949                  s == vmSymbols::java_lang_Float()) {
       
  1950         out_sig_bt[total_c_args-1] = T_INT;
       
  1951       } else if (s == vmSymbols::java_lang_Long() ||
       
  1952                  s == vmSymbols::java_lang_Double()) {
       
  1953         out_sig_bt[total_c_args-1] = T_LONG;
       
  1954         out_sig_bt[total_c_args++] = T_VOID;
       
  1955       }
       
  1956     } else if ( bt == T_LONG || bt == T_DOUBLE ) {
       
  1957       in_sig_bt[i++] = T_VOID;   // Longs & doubles take 2 Java slots
       
  1958       out_sig_bt[total_c_args++] = T_VOID;
       
  1959     }
       
  1960   }
       
  1961 
       
  1962   assert(i==total_args_passed, "validly parsed signature");
       
  1963 
       
  1964   // Now get the compiled-Java layout as input arguments
       
  1965   int comp_args_on_stack;
       
  1966   comp_args_on_stack = SharedRuntime::java_calling_convention(
       
  1967       in_sig_bt, in_regs, total_args_passed, false);
       
  1968 
       
  1969   // Now figure out where the args must be stored and how much stack space
       
  1970   // they require (neglecting out_preserve_stack_slots).
       
  1971 
       
  1972   int out_arg_slots;
       
  1973   out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args);
       
  1974 
       
  1975   // Calculate the total number of stack slots we will need.
       
  1976 
       
  1977   // First count the abi requirement plus all of the outgoing args
       
  1978   int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots;
       
  1979 
       
  1980   // Now space for the string(s) we must convert
       
  1981 
       
  1982   int* string_locs   = NEW_RESOURCE_ARRAY(int, total_strings + 1);
       
  1983   for (i = 0; i < total_strings ; i++) {
       
  1984     string_locs[i] = stack_slots;
       
  1985     stack_slots += max_dtrace_string_size / VMRegImpl::stack_slot_size;
       
  1986   }
       
  1987 
       
  1988   // + 2 for return address (which we own) and saved rbp,
       
  1989 
       
  1990   stack_slots += 2;
       
  1991 
       
  1992   // Ok The space we have allocated will look like:
       
  1993   //
       
  1994   //
       
  1995   // FP-> |                     |
       
  1996   //      |---------------------|
       
  1997   //      | string[n]           |
       
  1998   //      |---------------------| <- string_locs[n]
       
  1999   //      | string[n-1]         |
       
  2000   //      |---------------------| <- string_locs[n-1]
       
  2001   //      | ...                 |
       
  2002   //      | ...                 |
       
  2003   //      |---------------------| <- string_locs[1]
       
  2004   //      | string[0]           |
       
  2005   //      |---------------------| <- string_locs[0]
       
  2006   //      | outbound memory     |
       
  2007   //      | based arguments     |
       
  2008   //      |                     |
       
  2009   //      |---------------------|
       
  2010   //      |                     |
       
  2011   // SP-> | out_preserved_slots |
       
  2012   //
       
  2013   //
       
  2014 
       
  2015   // Now compute actual number of stack words we need rounding to make
       
  2016   // stack properly aligned.
       
  2017   stack_slots = round_to(stack_slots, 2 * VMRegImpl::slots_per_word);
       
  2018 
       
  2019   int stack_size = stack_slots * VMRegImpl::stack_slot_size;
       
  2020 
       
  2021   intptr_t start = (intptr_t)__ pc();
       
  2022 
       
  2023   // First thing make an ic check to see if we should even be here
       
  2024 
       
  2025   // We are free to use all registers as temps without saving them and
       
  2026   // restoring them except rbp. rbp, is the only callee save register
       
  2027   // as far as the interpreter and the compiler(s) are concerned.
       
  2028 
       
  2029   const Register ic_reg = rax;
       
  2030   const Register receiver = rcx;
       
  2031   Label hit;
       
  2032   Label exception_pending;
       
  2033 
       
  2034 
       
  2035   __ verify_oop(receiver);
       
  2036   __ cmpl(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes()));
       
  2037   __ jcc(Assembler::equal, hit);
       
  2038 
       
  2039   __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
       
  2040 
       
  2041   // verified entry must be aligned for code patching.
       
  2042   // and the first 5 bytes must be in the same cache line
       
  2043   // if we align at 8 then we will be sure 5 bytes are in the same line
       
  2044   __ align(8);
       
  2045 
       
  2046   __ bind(hit);
       
  2047 
       
  2048   int vep_offset = ((intptr_t)__ pc()) - start;
       
  2049 
       
  2050 
       
  2051   // The instruction at the verified entry point must be 5 bytes or longer
       
  2052   // because it can be patched on the fly by make_non_entrant. The stack bang
       
  2053   // instruction fits that requirement.
       
  2054 
       
  2055   // Generate stack overflow check
       
  2056 
       
  2057 
       
  2058   if (UseStackBanging) {
       
  2059     if (stack_size <= StackShadowPages*os::vm_page_size()) {
       
  2060       __ bang_stack_with_offset(StackShadowPages*os::vm_page_size());
       
  2061     } else {
       
  2062       __ movl(rax, stack_size);
       
  2063       __ bang_stack_size(rax, rbx);
       
  2064     }
       
  2065   } else {
       
  2066     // need a 5 byte instruction to allow MT safe patching to non-entrant
       
  2067     __ fat_nop();
       
  2068   }
       
  2069 
       
  2070   assert(((int)__ pc() - start - vep_offset) >= 5,
       
  2071          "valid size for make_non_entrant");
       
  2072 
       
  2073   // Generate a new frame for the wrapper.
       
  2074   __ enter();
       
  2075 
       
  2076   // -2 because return address is already present and so is saved rbp,
       
  2077   if (stack_size - 2*wordSize != 0) {
       
  2078     __ subl(rsp, stack_size - 2*wordSize);
       
  2079   }
       
  2080 
       
  2081   // Frame is now completed as far a size and linkage.
       
  2082 
       
  2083   int frame_complete = ((intptr_t)__ pc()) - start;
       
  2084 
       
  2085   // First thing we do store all the args as if we are doing the call.
       
  2086   // Since the C calling convention is stack based that ensures that
       
  2087   // all the Java register args are stored before we need to convert any
       
  2088   // string we might have.
       
  2089 
       
  2090   int sid = 0;
       
  2091   int c_arg, j_arg;
       
  2092   int string_reg = 0;
       
  2093 
       
  2094   for (j_arg = first_arg_to_pass, c_arg = 0 ;
       
  2095        j_arg < total_args_passed ; j_arg++, c_arg++ ) {
       
  2096 
       
  2097     VMRegPair src = in_regs[j_arg];
       
  2098     VMRegPair dst = out_regs[c_arg];
       
  2099     assert(dst.first()->is_stack() || in_sig_bt[j_arg] == T_VOID,
       
  2100            "stack based abi assumed");
       
  2101 
       
  2102     switch (in_sig_bt[j_arg]) {
       
  2103 
       
  2104       case T_ARRAY:
       
  2105       case T_OBJECT:
       
  2106         if (out_sig_bt[c_arg] == T_ADDRESS) {
       
  2107           // Any register based arg for a java string after the first
       
  2108           // will be destroyed by the call to get_utf so we store
       
  2109           // the original value in the location the utf string address
       
  2110           // will eventually be stored.
       
  2111           if (src.first()->is_reg()) {
       
  2112             if (string_reg++ != 0) {
       
  2113               simple_move32(masm, src, dst);
       
  2114             }
       
  2115           }
       
  2116         } else if (out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) {
       
  2117           // need to unbox a one-word value
       
  2118           Register in_reg = rax;
       
  2119           if ( src.first()->is_reg() ) {
       
  2120             in_reg = src.first()->as_Register();
       
  2121           } else {
       
  2122             simple_move32(masm, src, in_reg->as_VMReg());
       
  2123           }
       
  2124           Label skipUnbox;
       
  2125           __ movl(Address(rsp, reg2offset_out(dst.first())), NULL_WORD);
       
  2126           if ( out_sig_bt[c_arg] == T_LONG ) {
       
  2127             __ movl(Address(rsp, reg2offset_out(dst.second())), NULL_WORD);
       
  2128           }
       
  2129           __ testl(in_reg, in_reg);
       
  2130           __ jcc(Assembler::zero, skipUnbox);
       
  2131           assert(dst.first()->is_stack() &&
       
  2132                  (!dst.second()->is_valid() || dst.second()->is_stack()),
       
  2133                  "value(s) must go into stack slots");
       
  2134           if ( out_sig_bt[c_arg] == T_LONG ) {
       
  2135             __ movl(rbx, Address(in_reg,
       
  2136                                  box_offset + VMRegImpl::stack_slot_size));
       
  2137             __ movl(Address(rsp, reg2offset_out(dst.second())), rbx);
       
  2138           }
       
  2139           __ movl(in_reg,  Address(in_reg, box_offset));
       
  2140           __ movl(Address(rsp, reg2offset_out(dst.first())), in_reg);
       
  2141           __ bind(skipUnbox);
       
  2142         } else {
       
  2143           // Convert the arg to NULL
       
  2144           __ movl(Address(rsp, reg2offset_out(dst.first())), NULL_WORD);
       
  2145         }
       
  2146         if (out_sig_bt[c_arg] == T_LONG) {
       
  2147           assert(out_sig_bt[c_arg+1] == T_VOID, "must be");
       
  2148           ++c_arg; // Move over the T_VOID To keep the loop indices in sync
       
  2149         }
       
  2150         break;
       
  2151 
       
  2152       case T_VOID:
       
  2153         break;
       
  2154 
       
  2155       case T_FLOAT:
       
  2156         float_move(masm, src, dst);
       
  2157         break;
       
  2158 
       
  2159       case T_DOUBLE:
       
  2160         assert( j_arg + 1 < total_args_passed &&
       
  2161                 in_sig_bt[j_arg + 1] == T_VOID, "bad arg list");
       
  2162         double_move(masm, src, dst);
       
  2163         break;
       
  2164 
       
  2165       case T_LONG :
       
  2166         long_move(masm, src, dst);
       
  2167         break;
       
  2168 
       
  2169       case T_ADDRESS: assert(false, "found T_ADDRESS in java args");
       
  2170 
       
  2171       default:
       
  2172         simple_move32(masm, src, dst);
       
  2173     }
       
  2174   }
       
  2175 
       
  2176   // Now we must convert any string we have to utf8
       
  2177   //
       
  2178 
       
  2179   for (sid = 0, j_arg = first_arg_to_pass, c_arg = 0 ;
       
  2180        sid < total_strings ; j_arg++, c_arg++ ) {
       
  2181 
       
  2182     if (out_sig_bt[c_arg] == T_ADDRESS) {
       
  2183 
       
  2184       Address utf8_addr = Address(
       
  2185           rsp, string_locs[sid++] * VMRegImpl::stack_slot_size);
       
  2186       __ leal(rax, utf8_addr);
       
  2187 
       
  2188       // The first string we find might still be in the original java arg
       
  2189       // register
       
  2190       VMReg orig_loc = in_regs[j_arg].first();
       
  2191       Register string_oop;
       
  2192 
       
  2193       // This is where the argument will eventually reside
       
  2194       Address dest = Address(rsp, reg2offset_out(out_regs[c_arg].first()));
       
  2195 
       
  2196       if (sid == 1 && orig_loc->is_reg()) {
       
  2197         string_oop = orig_loc->as_Register();
       
  2198         assert(string_oop != rax, "smashed arg");
       
  2199       } else {
       
  2200 
       
  2201         if (orig_loc->is_reg()) {
       
  2202           // Get the copy of the jls object
       
  2203           __ movl(rcx, dest);
       
  2204         } else {
       
  2205           // arg is still in the original location
       
  2206           __ movl(rcx, Address(rbp, reg2offset_in(orig_loc)));
       
  2207         }
       
  2208         string_oop = rcx;
       
  2209 
       
  2210       }
       
  2211       Label nullString;
       
  2212       __ movl(dest, NULL_WORD);
       
  2213       __ testl(string_oop, string_oop);
       
  2214       __ jcc(Assembler::zero, nullString);
       
  2215 
       
  2216       // Now we can store the address of the utf string as the argument
       
  2217       __ movl(dest, rax);
       
  2218 
       
  2219       // And do the conversion
       
  2220       __ call_VM_leaf(CAST_FROM_FN_PTR(
       
  2221              address, SharedRuntime::get_utf), string_oop, rax);
       
  2222       __ bind(nullString);
       
  2223     }
       
  2224 
       
  2225     if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) {
       
  2226       assert(out_sig_bt[c_arg+1] == T_VOID, "must be");
       
  2227       ++c_arg; // Move over the T_VOID To keep the loop indices in sync
       
  2228     }
       
  2229   }
       
  2230 
       
  2231 
       
  2232   // Ok now we are done. Need to place the nop that dtrace wants in order to
       
  2233   // patch in the trap
       
  2234 
       
  2235   int patch_offset = ((intptr_t)__ pc()) - start;
       
  2236 
       
  2237   __ nop();
       
  2238 
       
  2239 
       
  2240   // Return
       
  2241 
       
  2242   __ leave();
       
  2243   __ ret(0);
       
  2244 
       
  2245   __ flush();
       
  2246 
       
  2247   nmethod *nm = nmethod::new_dtrace_nmethod(
       
  2248       method, masm->code(), vep_offset, patch_offset, frame_complete,
       
  2249       stack_slots / VMRegImpl::slots_per_word);
       
  2250   return nm;
       
  2251 
       
  2252 }
       
  2253 
       
  2254 #endif // HAVE_DTRACE_H
       
  2255 
  1883 // this function returns the adjust size (in number of words) to a c2i adapter
  2256 // this function returns the adjust size (in number of words) to a c2i adapter
  1884 // activation for use during deoptimization
  2257 // activation for use during deoptimization
  1885 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) {
  2258 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) {
  1886   return (callee_locals - callee_parameters) * Interpreter::stackElementWords();
  2259   return (callee_locals - callee_parameters) * Interpreter::stackElementWords();
  1887 }
  2260 }