Thu, 29 Mar 2018 06:53:04 -0400
8164480: Crash with assert(handler_address == SharedRuntime::compute_compiled_exc_handler(..) failed: Must be the same
Summary: Exception checking code needs to handle pre-allocated exceptions.
Reviewed-by: thartmann, kvn
1.1 --- a/src/share/vm/c1/c1_Runtime1.cpp Tue Apr 03 17:08:37 2018 -0700 1.2 +++ b/src/share/vm/c1/c1_Runtime1.cpp Thu Mar 29 06:53:04 2018 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -547,9 +547,8 @@ 1.11 // normal bytecode execution. 1.12 thread->clear_exception_oop_and_pc(); 1.13 1.14 - Handle original_exception(thread, exception()); 1.15 - 1.16 - continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false); 1.17 + bool recursive_exception = false; 1.18 + continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false, recursive_exception); 1.19 // If an exception was thrown during exception dispatch, the exception oop may have changed 1.20 thread->set_exception_oop(exception()); 1.21 thread->set_exception_pc(pc); 1.22 @@ -557,8 +556,9 @@ 1.23 // the exception cache is used only by non-implicit exceptions 1.24 // Update the exception cache only when there didn't happen 1.25 // another exception during the computation of the compiled 1.26 - // exception handler. 1.27 - if (continuation != NULL && original_exception() == exception()) { 1.28 + // exception handler. Checking for exception oop equality is not 1.29 + // sufficient because some exceptions are pre-allocated and reused. 1.30 + if (continuation != NULL && !recursive_exception) { 1.31 nm->add_handler_for_exception_and_pc(exception, pc, continuation); 1.32 } 1.33 }
2.1 --- a/src/share/vm/opto/runtime.cpp Tue Apr 03 17:08:37 2018 -0700 2.2 +++ b/src/share/vm/opto/runtime.cpp Thu Mar 29 06:53:04 2018 -0400 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -1234,17 +1234,23 @@ 2.11 force_unwind ? NULL : nm->handler_for_exception_and_pc(exception, pc); 2.12 2.13 if (handler_address == NULL) { 2.14 - Handle original_exception(thread, exception()); 2.15 - handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true); 2.16 + bool recursive_exception = false; 2.17 + handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception); 2.18 assert (handler_address != NULL, "must have compiled handler"); 2.19 // Update the exception cache only when the unwind was not forced 2.20 // and there didn't happen another exception during the computation of the 2.21 - // compiled exception handler. 2.22 - if (!force_unwind && original_exception() == exception()) { 2.23 + // compiled exception handler. Checking for exception oop equality is not 2.24 + // sufficient because some exceptions are pre-allocated and reused. 2.25 + if (!force_unwind && !recursive_exception) { 2.26 nm->add_handler_for_exception_and_pc(exception,pc,handler_address); 2.27 } 2.28 } else { 2.29 - assert(handler_address == SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true), "Must be the same"); 2.30 +#ifdef ASSERT 2.31 + bool recursive_exception = false; 2.32 + address computed_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception); 2.33 + assert(recursive_exception || (handler_address == computed_address), err_msg("Handler address inconsistency: " PTR_FORMAT " != " PTR_FORMAT, 2.34 + p2i(handler_address), p2i(computed_address))); 2.35 +#endif 2.36 } 2.37 } 2.38
3.1 --- a/src/share/vm/runtime/sharedRuntime.cpp Tue Apr 03 17:08:37 2018 -0700 3.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp Thu Mar 29 06:53:04 2018 -0400 3.3 @@ -639,7 +639,7 @@ 3.4 // ret_pc points into caller; we are returning caller's exception handler 3.5 // for given exception 3.6 address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception, 3.7 - bool force_unwind, bool top_frame_only) { 3.8 + bool force_unwind, bool top_frame_only, bool& recursive_exception_occurred) { 3.9 assert(nm != NULL, "must exist"); 3.10 ResourceMark rm; 3.11 3.12 @@ -667,6 +667,7 @@ 3.13 // BCI of the exception handler which caused the exception to be 3.14 // thrown (bugs 4307310 and 4546590). Set "exception" reference 3.15 // argument to ensure that the correct exception is thrown (4870175). 3.16 + recursive_exception_occurred = true; 3.17 exception = Handle(THREAD, PENDING_EXCEPTION); 3.18 CLEAR_PENDING_EXCEPTION; 3.19 if (handler_bci >= 0) {
4.1 --- a/src/share/vm/runtime/sharedRuntime.hpp Tue Apr 03 17:08:37 2018 -0700 4.2 +++ b/src/share/vm/runtime/sharedRuntime.hpp Thu Mar 29 06:53:04 2018 -0400 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -184,7 +184,7 @@ 4.11 4.12 // exception handling and implicit exceptions 4.13 static address compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception, 4.14 - bool force_unwind, bool top_frame_only); 4.15 + bool force_unwind, bool top_frame_only, bool& recursive_exception_occurred); 4.16 enum ImplicitExceptionKind { 4.17 IMPLICIT_NULL, 4.18 IMPLICIT_DIVIDE_BY_ZERO,