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 } |