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
Contributed-by: serguei.spitsyn@oracle.com
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp Thu Jul 10 08:15:30 2014 -0700
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp Thu Jul 10 17:46:35 2014 -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
--- a/hotspot/src/share/vm/interpreter/oopMapCache.hpp Thu Jul 10 08:15:30 2014 -0700
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.hpp Thu Jul 10 17:46:35 2014 -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; }
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Thu Jul 10 08:15:30 2014 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Thu Jul 10 17:46:35 2014 -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,