# HG changeset patch # User sspitsyn # Date 1427437029 25200 # Node ID 9cfc607cb03ed6f938b20f6dd996765cc68461f9 # Parent e982379a7119a68c8b34af7d0b6e0c23698d6899 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 diff -r e982379a7119 -r 9cfc607cb03e src/share/vm/interpreter/oopMapCache.cpp --- a/src/share/vm/interpreter/oopMapCache.cpp Fri Mar 27 02:17:16 2015 +0000 +++ b/src/share/vm/interpreter/oopMapCache.cpp Thu Mar 26 23:17:09 2015 -0700 @@ -244,10 +244,8 @@ method()->print_value(); tty->print(" @ %d = [%d] { ", bci(), n); for (int i = 0; i < n; i++) { -#ifdef ENABLE_ZAP_DEAD_LOCALS if (is_dead(i)) tty->print("%d+ ", i); else -#endif if (is_oop(i)) tty->print("%d ", i); } tty->print_cr("}"); @@ -402,13 +400,11 @@ value |= (mask << oop_bit_number ); } - #ifdef ENABLE_ZAP_DEAD_LOCALS // set dead bit if (!cell->is_live()) { value |= (mask << dead_bit_number); assert(!cell->is_reference(), "dead value marked as oop"); } - #endif } // make sure last word is stored diff -r e982379a7119 -r 9cfc607cb03e src/share/vm/interpreter/oopMapCache.hpp --- a/src/share/vm/interpreter/oopMapCache.hpp Fri Mar 27 02:17:16 2015 +0000 +++ b/src/share/vm/interpreter/oopMapCache.hpp Thu Mar 26 23:17:09 2015 -0700 @@ -66,19 +66,15 @@ public: enum { - N = 2, // the number of words reserved + N = 4, // the number of words reserved // for inlined mask storage small_mask_limit = N * BitsPerWord, // the maximum number of bits // available for small masks, // small_mask_limit can be set to 0 // for testing bit_mask allocation -#ifdef ENABLE_ZAP_DEAD_LOCALS bits_per_entry = 2, dead_bit_number = 1, -#else - bits_per_entry = 1, -#endif oop_bit_number = 0 }; @@ -119,10 +115,6 @@ void set_expression_stack_size(int sz) { _expression_stack_size = sz; } -#ifdef ENABLE_ZAP_DEAD_LOCALS - bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; } -#endif - // Lookup bool match(methodHandle method, int bci) const { return _method == method() && _bci == bci; } bool is_empty() const; @@ -144,6 +136,7 @@ void print() const; int number_of_entries() const { return mask_size() / bits_per_entry; } + bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; } bool is_oop (int offset) const { return (entry_at(offset) & (1 << oop_bit_number )) != 0; } int expression_stack_size() const { return _expression_stack_size; } diff -r e982379a7119 -r 9cfc607cb03e src/share/vm/prims/jvmtiImpl.cpp --- a/src/share/vm/prims/jvmtiImpl.cpp Fri Mar 27 02:17:16 2015 +0000 +++ b/src/share/vm/prims/jvmtiImpl.cpp Thu Mar 26 23:17:09 2015 -0700 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/systemDictionary.hpp" #include "interpreter/interpreter.hpp" +#include "interpreter/oopMapCache.hpp" #include "jvmtifiles/jvmtiEnv.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" @@ -744,6 +745,13 @@ } void VM_GetOrSetLocal::doit() { + InterpreterOopMap oop_mask; + _jvf->method()->mask_for(_jvf->bci(), &oop_mask); + if (oop_mask.is_dead(_index)) { + // The local can be invalid and uninitialized in the scope of current bci + _result = JVMTI_ERROR_INVALID_SLOT; + return; + } if (_set) { // Force deoptimization of frame if compiled because it's // possible the compiler emitted some locals as constant values,