Created
April 15, 2014 07:03
-
-
Save Fuud/10709048 to your computer and use it in GitHub Desktop.
Patch to add more information if NPE occures in interpreter or template interpreter.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 5380dc5d007e src/cpu/sparc/vm/templateInterpreter_sparc.cpp | |
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Feb 28 13:36:09 2014 -0800 | |
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Sun Apr 13 10:47:04 2014 -0400 | |
@@ -93,6 +93,10 @@ | |
#endif | |
} | |
+address TemplateInterpreterGenerator::generate_NullPointer_handler() { | |
+ return generate_exception_handler("java/lang/NullPointerException", NULL); | |
+} | |
+ | |
address TemplateInterpreterGenerator::generate_exception_handler_common(const char* name, const char* message, bool pass_oop) { | |
assert(!pass_oop || message == NULL, "either oop or message but not both"); | |
address entry = __ pc(); | |
diff -r 5380dc5d007e src/cpu/x86/vm/templateInterpreter_x86_32.cpp | |
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Feb 28 13:36:09 2014 -0800 | |
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Sun Apr 13 10:47:04 2014 -0400 | |
@@ -113,6 +113,10 @@ | |
return entry; | |
} | |
+address TemplateInterpreterGenerator::generate_NullPointer_handler() { | |
+ return generate_exception_handler("java/lang/NullPointerException", NULL); | |
+} | |
+ | |
address TemplateInterpreterGenerator::generate_exception_handler_common(const char* name, const char* message, bool pass_oop) { | |
assert(!pass_oop || message == NULL, "either oop or message but not both"); | |
address entry = __ pc(); | |
diff -r 5380dc5d007e src/cpu/x86/vm/templateInterpreter_x86_64.cpp | |
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Feb 28 13:36:09 2014 -0800 | |
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Sun Apr 13 10:47:04 2014 -0400 | |
@@ -121,6 +121,32 @@ | |
return entry; | |
} | |
+address TemplateInterpreterGenerator::generate_NullPointer_handler() { | |
+ address entry = __ pc(); | |
+ | |
+ char* (*fptr)(Method*) = &Method::name_and_sig_as_C_string; | |
+ | |
+ const char * name = "java/lang/NullPointerException"; | |
+ // expression stack must be empty before entering the VM if an | |
+ // exception happened | |
+ __ empty_expression_stack(); | |
+ | |
+ __ mov(c_rarg0, rbx); | |
+ __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, fptr))); | |
+ | |
+ // setup parameters | |
+ __ lea(c_rarg1, ExternalAddress((address)name)); | |
+ __ mov(c_rarg2, rax); | |
+ | |
+ __ call_VM(rax, | |
+ CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), | |
+ c_rarg1, c_rarg2); | |
+ | |
+ // throw exception | |
+ __ jump(ExternalAddress(Interpreter::throw_exception_entry())); | |
+ return entry; | |
+} | |
+ | |
address TemplateInterpreterGenerator::generate_exception_handler_common( | |
const char* name, const char* message, bool pass_oop) { | |
assert(!pass_oop || message == NULL, "either oop or message but not both"); | |
diff -r 5380dc5d007e src/share/vm/interpreter/linkResolver.cpp | |
--- a/src/share/vm/interpreter/linkResolver.cpp Fri Feb 28 13:36:09 2014 -0800 | |
+++ b/src/share/vm/interpreter/linkResolver.cpp Sun Apr 13 10:47:04 2014 -0400 | |
@@ -46,6 +46,8 @@ | |
#include "runtime/thread.inline.hpp" | |
#include "runtime/vmThread.hpp" | |
+#include <stdio.h> | |
+ | |
//------------------------------------------------------------------------------------------------------------------------ | |
// Implementation of CallInfo | |
@@ -1161,12 +1163,13 @@ | |
// setup default return values | |
int vtable_index = Method::invalid_vtable_index; | |
methodHandle selected_method; | |
+ | |
assert(recv.is_null() || recv->is_oop(), "receiver is not an oop"); | |
// runtime method resolution | |
if (check_null_and_abstract && recv.is_null()) { // check if receiver exists | |
- THROW(vmSymbols::java_lang_NullPointerException()); | |
+ throw_null_pointer_exception(resolved_method, CHECK); | |
} | |
// Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s | |
@@ -1268,9 +1271,9 @@ | |
Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) { | |
// check if receiver exists | |
if (check_null_and_abstract && recv.is_null()) { | |
- THROW(vmSymbols::java_lang_NullPointerException()); | |
+ throw_null_pointer_exception(resolved_method, CHECK); | |
} | |
- | |
+ | |
// check if private interface method | |
if (resolved_klass->is_interface() && resolved_method->is_private()) { | |
ResourceMark rm(THREAD); | |
@@ -1652,6 +1655,14 @@ | |
result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK); | |
} | |
+void LinkResolver::throw_null_pointer_exception(methodHandle& resolved_method, TRAPS){ | |
+ const char* msgTemplate = "can not invoke method %s on null object"; | |
+ const char* methodSig= resolved_method->name_and_sig_as_C_string(); | |
+ char * message = NEW_RESOURCE_ARRAY(char, strlen(msgTemplate)+strlen(methodSig)); | |
+ sprintf (message, msgTemplate, methodSig); | |
+ THROW_MSG(vmSymbols::java_lang_NullPointerException(), message); | |
+} | |
+ | |
//------------------------------------------------------------------------------------------------------------------------ | |
#ifndef PRODUCT | |
diff -r 5380dc5d007e src/share/vm/interpreter/linkResolver.hpp | |
--- a/src/share/vm/interpreter/linkResolver.hpp Fri Feb 28 13:36:09 2014 -0800 | |
+++ b/src/share/vm/interpreter/linkResolver.hpp Sun Apr 13 10:47:04 2014 -0400 | |
@@ -148,6 +148,7 @@ | |
static void check_field_accessability (KlassHandle ref_klass, KlassHandle resolved_klass, KlassHandle sel_klass, fieldDescriptor& fd, TRAPS); | |
static void check_method_accessability (KlassHandle ref_klass, KlassHandle resolved_klass, KlassHandle sel_klass, methodHandle sel_method, TRAPS); | |
+ static void throw_null_pointer_exception(methodHandle& resolved_method, TRAPS); | |
public: | |
// constant pool resolving | |
diff -r 5380dc5d007e src/share/vm/interpreter/templateInterpreter.cpp | |
--- a/src/share/vm/interpreter/templateInterpreter.cpp Fri Feb 28 13:36:09 2014 -0800 | |
+++ b/src/share/vm/interpreter/templateInterpreter.cpp Sun Apr 13 10:47:04 2014 -0400 | |
@@ -354,7 +354,7 @@ | |
Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); | |
Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); | |
Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); | |
- Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); | |
+ Interpreter::_throw_NullPointerException_entry = generate_NullPointer_handler(); | |
Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); | |
} | |
diff -r 5380dc5d007e src/share/vm/interpreter/templateInterpreterGenerator.hpp | |
--- a/src/share/vm/interpreter/templateInterpreterGenerator.hpp Fri Feb 28 13:36:09 2014 -0800 | |
+++ b/src/share/vm/interpreter/templateInterpreterGenerator.hpp Sun Apr 13 10:47:04 2014 -0400 | |
@@ -52,6 +52,7 @@ | |
address generate_exception_handler_common(const char* name, const char* message, bool pass_oop); | |
address generate_ClassCastException_handler(); | |
address generate_ArrayIndexOutOfBounds_handler(const char* name); | |
+ address generate_NullPointer_handler(); | |
address generate_continuation_for(TosState state); | |
address generate_return_entry_for(TosState state, int step, size_t index_size); | |
address generate_earlyret_entry_for(TosState state); | |
diff -r 5380dc5d007e src/share/vm/oops/method.cpp | |
--- a/src/share/vm/oops/method.cpp Fri Feb 28 13:36:09 2014 -0800 | |
+++ b/src/share/vm/oops/method.cpp Sun Apr 13 10:47:04 2014 -0400 | |
@@ -136,7 +136,12 @@ | |
} | |
char* Method::name_and_sig_as_C_string() const { | |
- return name_and_sig_as_C_string(constants()->pool_holder(), name(), signature()); | |
+ return name_and_sig_as_C_string(constants()->pool_holder(), name(), signature()); | |
+} | |
+ | |
+ | |
+char* Method::name_and_sig_as_C_string(Method* method){ | |
+ return method->name_and_sig_as_C_string(); | |
} | |
char* Method::name_and_sig_as_C_string(char* buf, int size) const { | |
diff -r 5380dc5d007e src/share/vm/oops/method.hpp | |
--- a/src/share/vm/oops/method.hpp Fri Feb 28 13:36:09 2014 -0800 | |
+++ b/src/share/vm/oops/method.hpp Sun Apr 13 10:47:04 2014 -0400 | |
@@ -212,6 +212,7 @@ | |
char* name_and_sig_as_C_string(char* buf, int size) const; | |
// Static routine in the situations we don't have a Method* | |
+ static char* name_and_sig_as_C_string(Method* method); | |
static char* name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature); | |
static char* name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature, char* buf, int size); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment