Mercurial > hg > truffle
comparison src/share/vm/runtime/sharedRuntime.cpp @ 1295:3cf667df43ef
6919934: JSR 292 needs to support x86 C1
Summary: This implements JSR 292 support for C1 x86.
Reviewed-by: never, jrose, kvn
author | twisti |
---|---|
date | Tue, 09 Mar 2010 20:16:19 +0100 |
parents | e7b1cc79bd25 |
children | 9eba43136cb5 |
comparison
equal
deleted
inserted
replaced
1293:51db1e4b379d | 1295:3cf667df43ef |
---|---|
254 // | 254 // |
255 // exception_handler_for_return_address(...) returns the continuation address. | 255 // exception_handler_for_return_address(...) returns the continuation address. |
256 // The continuation address is the entry point of the exception handler of the | 256 // The continuation address is the entry point of the exception handler of the |
257 // previous frame depending on the return address. | 257 // previous frame depending on the return address. |
258 | 258 |
259 address SharedRuntime::raw_exception_handler_for_return_address(address return_address) { | 259 address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) { |
260 assert(frame::verify_return_pc(return_address), "must be a return pc"); | 260 assert(frame::verify_return_pc(return_address), "must be a return pc"); |
261 | 261 |
262 // the fastest case first | 262 // the fastest case first |
263 CodeBlob* blob = CodeCache::find_blob(return_address); | 263 CodeBlob* blob = CodeCache::find_blob(return_address); |
264 if (blob != NULL && blob->is_nmethod()) { | 264 if (blob != NULL && blob->is_nmethod()) { |
265 nmethod* code = (nmethod*)blob; | 265 nmethod* code = (nmethod*)blob; |
266 assert(code != NULL, "nmethod must be present"); | 266 assert(code != NULL, "nmethod must be present"); |
267 // Check if the return address is a MethodHandle call site. | |
268 thread->set_is_method_handle_exception(code->is_method_handle_return(return_address)); | |
267 // native nmethods don't have exception handlers | 269 // native nmethods don't have exception handlers |
268 assert(!code->is_native_method(), "no exception handler"); | 270 assert(!code->is_native_method(), "no exception handler"); |
269 assert(code->header_begin() != code->exception_begin(), "no exception handler"); | 271 assert(code->header_begin() != code->exception_begin(), "no exception handler"); |
270 if (code->is_deopt_pc(return_address)) { | 272 if (code->is_deopt_pc(return_address)) { |
271 return SharedRuntime::deopt_blob()->unpack_with_exception(); | 273 return SharedRuntime::deopt_blob()->unpack_with_exception(); |
287 if (CodeCache::contains(return_address)) { | 289 if (CodeCache::contains(return_address)) { |
288 CodeBlob* blob = CodeCache::find_blob(return_address); | 290 CodeBlob* blob = CodeCache::find_blob(return_address); |
289 if (blob->is_nmethod()) { | 291 if (blob->is_nmethod()) { |
290 nmethod* code = (nmethod*)blob; | 292 nmethod* code = (nmethod*)blob; |
291 assert(code != NULL, "nmethod must be present"); | 293 assert(code != NULL, "nmethod must be present"); |
294 // Check if the return address is a MethodHandle call site. | |
295 thread->set_is_method_handle_exception(code->is_method_handle_return(return_address)); | |
292 assert(code->header_begin() != code->exception_begin(), "no exception handler"); | 296 assert(code->header_begin() != code->exception_begin(), "no exception handler"); |
293 return code->exception_begin(); | 297 return code->exception_begin(); |
294 } | 298 } |
295 if (blob->is_runtime_stub()) { | 299 if (blob->is_runtime_stub()) { |
296 ShouldNotReachHere(); // callers are responsible for skipping runtime stub frames | 300 ShouldNotReachHere(); // callers are responsible for skipping runtime stub frames |
307 ShouldNotReachHere(); | 311 ShouldNotReachHere(); |
308 return NULL; | 312 return NULL; |
309 } | 313 } |
310 | 314 |
311 | 315 |
312 JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(address return_address)) | 316 JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(JavaThread* thread, address return_address)) |
313 return raw_exception_handler_for_return_address(return_address); | 317 return raw_exception_handler_for_return_address(thread, return_address); |
314 JRT_END | 318 JRT_END |
319 | |
315 | 320 |
316 address SharedRuntime::get_poll_stub(address pc) { | 321 address SharedRuntime::get_poll_stub(address pc) { |
317 address stub; | 322 address stub; |
318 // Look up the code blob | 323 // Look up the code blob |
319 CodeBlob *cb = CodeCache::find_blob(pc); | 324 CodeBlob *cb = CodeCache::find_blob(pc); |
463 // synchonized methods since the unlock path isn't represented in | 468 // synchonized methods since the unlock path isn't represented in |
464 // the bytecodes. | 469 // the bytecodes. |
465 t = table.entry_for(catch_pco, -1, 0); | 470 t = table.entry_for(catch_pco, -1, 0); |
466 } | 471 } |
467 | 472 |
468 #ifdef COMPILER1 | |
469 if (nm->is_compiled_by_c1() && t == NULL && handler_bci == -1) { | |
470 // Exception is not handled by this frame so unwind. Note that | |
471 // this is not the same as how C2 does this. C2 emits a table | |
472 // entry that dispatches to the unwind code in the nmethod. | |
473 return NULL; | |
474 } | |
475 #endif /* COMPILER1 */ | |
476 | |
477 | |
478 if (t == NULL) { | 473 if (t == NULL) { |
479 tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", ret_pc, handler_bci); | 474 tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", ret_pc, handler_bci); |
480 tty->print_cr(" Exception:"); | 475 tty->print_cr(" Exception:"); |
481 exception->print(); | 476 exception->print(); |
482 tty->cr(); | 477 tty->cr(); |
890 | 885 |
891 ResourceMark rm(thread); | 886 ResourceMark rm(thread); |
892 RegisterMap cbl_map(thread, false); | 887 RegisterMap cbl_map(thread, false); |
893 frame caller_frame = thread->last_frame().sender(&cbl_map); | 888 frame caller_frame = thread->last_frame().sender(&cbl_map); |
894 | 889 |
895 CodeBlob* cb = caller_frame.cb(); | 890 CodeBlob* caller_cb = caller_frame.cb(); |
896 guarantee(cb != NULL && cb->is_nmethod(), "must be called from nmethod"); | 891 guarantee(caller_cb != NULL && caller_cb->is_nmethod(), "must be called from nmethod"); |
892 nmethod* caller_nm = caller_cb->as_nmethod_or_null(); | |
897 // make sure caller is not getting deoptimized | 893 // make sure caller is not getting deoptimized |
898 // and removed before we are done with it. | 894 // and removed before we are done with it. |
899 // CLEANUP - with lazy deopt shouldn't need this lock | 895 // CLEANUP - with lazy deopt shouldn't need this lock |
900 nmethodLocker caller_lock((nmethod*)cb); | 896 nmethodLocker caller_lock(caller_nm); |
901 | 897 |
902 | 898 |
903 // determine call info & receiver | 899 // determine call info & receiver |
904 // note: a) receiver is NULL for static calls | 900 // note: a) receiver is NULL for static calls |
905 // b) an exception is thrown if receiver is NULL for non-static calls | 901 // b) an exception is thrown if receiver is NULL for non-static calls |
927 callee_method->print_short_name(tty); | 923 callee_method->print_short_name(tty); |
928 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code()); | 924 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code()); |
929 } | 925 } |
930 #endif | 926 #endif |
931 | 927 |
928 // JSR 292 | |
929 // If the resolved method is a MethodHandle invoke target the call | |
930 // site must be a MethodHandle call site. | |
931 if (callee_method->is_method_handle_invoke()) { | |
932 assert(caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site"); | |
933 } | |
934 | |
932 // Compute entry points. This might require generation of C2I converter | 935 // Compute entry points. This might require generation of C2I converter |
933 // frames, so we cannot be holding any locks here. Furthermore, the | 936 // frames, so we cannot be holding any locks here. Furthermore, the |
934 // computation of the entry points is independent of patching the call. We | 937 // computation of the entry points is independent of patching the call. We |
935 // always return the entry-point, but we only patch the stub if the call has | 938 // always return the entry-point, but we only patch the stub if the call has |
936 // not been deoptimized. Return values: For a virtual call this is an | 939 // not been deoptimized. Return values: For a virtual call this is an |
938 // virtual this is just a destination address. | 941 // virtual this is just a destination address. |
939 | 942 |
940 StaticCallInfo static_call_info; | 943 StaticCallInfo static_call_info; |
941 CompiledICInfo virtual_call_info; | 944 CompiledICInfo virtual_call_info; |
942 | 945 |
943 | |
944 // Make sure the callee nmethod does not get deoptimized and removed before | 946 // Make sure the callee nmethod does not get deoptimized and removed before |
945 // we are done patching the code. | 947 // we are done patching the code. |
946 nmethod* nm = callee_method->code(); | 948 nmethod* callee_nm = callee_method->code(); |
947 nmethodLocker nl_callee(nm); | 949 nmethodLocker nl_callee(callee_nm); |
948 #ifdef ASSERT | 950 #ifdef ASSERT |
949 address dest_entry_point = nm == NULL ? 0 : nm->entry_point(); // used below | 951 address dest_entry_point = callee_nm == NULL ? 0 : callee_nm->entry_point(); // used below |
950 #endif | 952 #endif |
951 | 953 |
952 if (is_virtual) { | 954 if (is_virtual) { |
953 assert(receiver.not_null(), "sanity check"); | 955 assert(receiver.not_null(), "sanity check"); |
954 bool static_bound = call_info.resolved_method()->can_be_statically_bound(); | 956 bool static_bound = call_info.resolved_method()->can_be_statically_bound(); |