Thu, 26 Mar 2015 23:17:09 -0700
8013942: JSR 292: assert(type() == T_OBJECT) failed: type check
Summary: A dead scope of the local needs to be identified
Reviewed-by: coleenp, vlivanov, mgronlun
1.1 --- a/src/share/vm/interpreter/oopMapCache.cpp Fri Mar 27 02:17:16 2015 +0000 1.2 +++ b/src/share/vm/interpreter/oopMapCache.cpp Thu Mar 26 23:17:09 2015 -0700 1.3 @@ -244,10 +244,8 @@ 1.4 method()->print_value(); 1.5 tty->print(" @ %d = [%d] { ", bci(), n); 1.6 for (int i = 0; i < n; i++) { 1.7 -#ifdef ENABLE_ZAP_DEAD_LOCALS 1.8 if (is_dead(i)) tty->print("%d+ ", i); 1.9 else 1.10 -#endif 1.11 if (is_oop(i)) tty->print("%d ", i); 1.12 } 1.13 tty->print_cr("}"); 1.14 @@ -402,13 +400,11 @@ 1.15 value |= (mask << oop_bit_number ); 1.16 } 1.17 1.18 - #ifdef ENABLE_ZAP_DEAD_LOCALS 1.19 // set dead bit 1.20 if (!cell->is_live()) { 1.21 value |= (mask << dead_bit_number); 1.22 assert(!cell->is_reference(), "dead value marked as oop"); 1.23 } 1.24 - #endif 1.25 } 1.26 1.27 // make sure last word is stored
2.1 --- a/src/share/vm/interpreter/oopMapCache.hpp Fri Mar 27 02:17:16 2015 +0000 2.2 +++ b/src/share/vm/interpreter/oopMapCache.hpp Thu Mar 26 23:17:09 2015 -0700 2.3 @@ -66,19 +66,15 @@ 2.4 2.5 public: 2.6 enum { 2.7 - N = 2, // the number of words reserved 2.8 + N = 4, // the number of words reserved 2.9 // for inlined mask storage 2.10 small_mask_limit = N * BitsPerWord, // the maximum number of bits 2.11 // available for small masks, 2.12 // small_mask_limit can be set to 0 2.13 // for testing bit_mask allocation 2.14 2.15 -#ifdef ENABLE_ZAP_DEAD_LOCALS 2.16 bits_per_entry = 2, 2.17 dead_bit_number = 1, 2.18 -#else 2.19 - bits_per_entry = 1, 2.20 -#endif 2.21 oop_bit_number = 0 2.22 }; 2.23 2.24 @@ -119,10 +115,6 @@ 2.25 2.26 void set_expression_stack_size(int sz) { _expression_stack_size = sz; } 2.27 2.28 -#ifdef ENABLE_ZAP_DEAD_LOCALS 2.29 - bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; } 2.30 -#endif 2.31 - 2.32 // Lookup 2.33 bool match(methodHandle method, int bci) const { return _method == method() && _bci == bci; } 2.34 bool is_empty() const; 2.35 @@ -144,6 +136,7 @@ 2.36 void print() const; 2.37 2.38 int number_of_entries() const { return mask_size() / bits_per_entry; } 2.39 + bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; } 2.40 bool is_oop (int offset) const { return (entry_at(offset) & (1 << oop_bit_number )) != 0; } 2.41 2.42 int expression_stack_size() const { return _expression_stack_size; }
3.1 --- a/src/share/vm/prims/jvmtiImpl.cpp Fri Mar 27 02:17:16 2015 +0000 3.2 +++ b/src/share/vm/prims/jvmtiImpl.cpp Thu Mar 26 23:17:09 2015 -0700 3.3 @@ -25,6 +25,7 @@ 3.4 #include "precompiled.hpp" 3.5 #include "classfile/systemDictionary.hpp" 3.6 #include "interpreter/interpreter.hpp" 3.7 +#include "interpreter/oopMapCache.hpp" 3.8 #include "jvmtifiles/jvmtiEnv.hpp" 3.9 #include "memory/resourceArea.hpp" 3.10 #include "oops/instanceKlass.hpp" 3.11 @@ -744,6 +745,13 @@ 3.12 } 3.13 3.14 void VM_GetOrSetLocal::doit() { 3.15 + InterpreterOopMap oop_mask; 3.16 + _jvf->method()->mask_for(_jvf->bci(), &oop_mask); 3.17 + if (oop_mask.is_dead(_index)) { 3.18 + // The local can be invalid and uninitialized in the scope of current bci 3.19 + _result = JVMTI_ERROR_INVALID_SLOT; 3.20 + return; 3.21 + } 3.22 if (_set) { 3.23 // Force deoptimization of frame if compiled because it's 3.24 // possible the compiler emitted some locals as constant values,