Skip to content

Instantly share code, notes, and snippets.

@Fuud
Created April 15, 2014 07:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fuud/10709048 to your computer and use it in GitHub Desktop.
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.
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