< prev index next >

src/hotspot/share/runtime/frame.cpp

Print this page

        

@@ -34,10 +34,11 @@
 #include "memory/universe.inline.hpp"
 #include "oops/markOop.hpp"
 #include "oops/method.hpp"
 #include "oops/methodData.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/valueKlass.hpp"
 #include "oops/verifyOopClosure.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"

@@ -760,34 +761,36 @@
   frame* _fr;
   OopClosure* _f;
   BufferedValueClosure* _bvt_f;
   int    _max_locals;
   int    _max_stack;
+  BufferedValuesDealiaser* _dealiaser;
 
  public:
   InterpreterFrameClosure(frame* fr, int max_locals, int max_stack,
                           OopClosure* f, BufferedValueClosure* bvt_f) {
     _fr         = fr;
     _max_locals = max_locals;
     _max_stack  = max_stack;
     _f          = f;
     _bvt_f      = bvt_f;
+    _dealiaser  = NULL;
   }
 
   void offset_do(int offset) {
     oop* addr;
     if (offset < _max_locals) {
       addr = (oop*) _fr->interpreter_frame_local_at(offset);
       assert((intptr_t*)addr >= _fr->sp(), "must be inside the frame");
-      if (Universe::heap()->is_in_reserved_or_null(*addr)) {
+      if (!VTBuffer::is_in_vt_buffer(*addr)) {
         if (_f != NULL) {
           _f->do_oop(addr);
         }
       } else { // Buffered value types case
+        assert((*addr)->is_value(), "Only values can be buffered");
         if (_f != NULL) {
-          oop* addr_mirror = (oop*)(*addr)->mark_addr();
-          _f->do_oop(addr_mirror);
+          dealiaser()->oops_do(_f, *addr);
         }
         if (_bvt_f != NULL) {
           _bvt_f->do_buffered_value(addr);
         }
       }

@@ -800,18 +803,18 @@
         in_stack = (intptr_t*)addr <= _fr->interpreter_frame_tos_address();
       } else {
         in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address();
       }
       if (in_stack) {
-        if (Universe::heap()->is_in_reserved_or_null(*addr)) {
+        if (!VTBuffer::is_in_vt_buffer(*addr)) {
           if (_f != NULL) {
             _f->do_oop(addr);
           }
         } else { // Buffered value types case
+          assert((*addr)->is_value(), "Only values can be buffered");
           if (_f != NULL) {
-            oop* addr_mirror = (oop*)(*addr)->mark_addr();
-            _f->do_oop(addr_mirror);
+            dealiaser()->oops_do(_f, *addr);
           }
           if (_bvt_f != NULL) {
             _bvt_f->do_buffered_value(addr);
           }
         }

@@ -819,29 +822,44 @@
     }
   }
 
   int max_locals()  { return _max_locals; }
   frame* fr()       { return _fr; }
+
+ private:
+  BufferedValuesDealiaser* dealiaser() {
+    if (_dealiaser == NULL) {
+      _dealiaser = Thread::current()->buffered_values_dealiaser();
+      assert(_dealiaser != NULL, "Must not be NULL");
+    }
+    return _dealiaser;
+  }
 };
 
 
 class InterpretedArgumentOopFinder: public SignatureInfo {
  private:
   OopClosure* _f;        // Closure to invoke
   int    _offset;        // TOS-relative offset, decremented with each argument
   bool   _has_receiver;  // true if the callee has a receiver
   frame* _fr;
+  BufferedValuesDealiaser* _dealiaser;
 
   void set(int size, BasicType type) {
     _offset -= size;
     if (type == T_OBJECT || type == T_ARRAY || type == T_VALUETYPE) oop_offset_do();
   }
 
   void oop_offset_do() {
     oop* addr;
     addr = (oop*)_fr->interpreter_frame_tos_at(_offset);
+    if (!VTBuffer::is_in_vt_buffer(*addr)) {
     _f->do_oop(addr);
+    } else { // Buffered value types case
+      assert((*addr)->is_value(), "Only values can be buffered");
+      dealiaser()->oops_do(_f, *addr);
+    }
   }
 
  public:
   InterpretedArgumentOopFinder(Symbol* signature, bool has_receiver, frame* fr, OopClosure* f) : SignatureInfo(signature), _has_receiver(has_receiver) {
     // compute size of arguments

@@ -851,10 +869,19 @@
             "args cannot be on stack anymore");
     // initialize InterpretedArgumentOopFinder
     _f         = f;
     _fr        = fr;
     _offset    = args_size;
+    _dealiaser = NULL;
+  }
+
+  BufferedValuesDealiaser* dealiaser() {
+    if (_dealiaser == NULL) {
+      _dealiaser = Thread::current()->buffered_values_dealiaser();
+      assert(_dealiaser != NULL, "Must not be NULL");
+    }
+    return _dealiaser;
   }
 
   void oops_do() {
     if (_has_receiver) {
       --_offset;

@@ -881,29 +908,44 @@
  private:
   bool   _is_static;
   int    _offset;
   frame* _fr;
   OopClosure* _f;
+  BufferedValuesDealiaser* _dealiaser;
+
+  BufferedValuesDealiaser* dealiaser() {
+    if (_dealiaser == NULL) {
+      _dealiaser = Thread::current()->buffered_values_dealiaser();
+      assert(_dealiaser != NULL, "Must not be NULL");
+    }
+    return _dealiaser;
+  }
 
   void set(int size, BasicType type) {
     assert (_offset >= 0, "illegal offset");
     if (type == T_OBJECT || type == T_ARRAY || type == T_VALUETYPE) oop_at_offset_do(_offset);
     _offset -= size;
   }
 
   void oop_at_offset_do(int offset) {
     assert (offset >= 0, "illegal offset");
     oop* addr = (oop*) _fr->entry_frame_argument_at(offset);
+    if (!VTBuffer::is_in_vt_buffer(*addr)) {
     _f->do_oop(addr);
+    } else { // Buffered value types case
+      assert((*addr)->is_value(), "Only values can be buffered");
+      dealiaser()->oops_do(_f, *addr);
+    }
   }
 
  public:
    EntryFrameOopFinder(frame* frame, Symbol* signature, bool is_static) : SignatureInfo(signature) {
      _f = NULL; // will be set later
      _fr = frame;
      _is_static = is_static;
      _offset = ArgumentSizeComputer(signature).size() - 1; // last parameter is at index 0
+     _dealiaser = NULL;
    }
 
   void arguments_do(OopClosure* f) {
     _f = f;
     if (!_is_static) oop_at_offset_do(_offset+1); // do the receiver

@@ -944,10 +986,11 @@
 #endif
     current->oops_do(f);
   }
 
   if (m->is_native()) {
+    assert(!VTBuffer::is_in_vt_buffer((oopDesc*)*interpreter_frame_temp_oop_addr()), "Sanity check");
     f->do_oop(interpreter_frame_temp_oop_addr());
   }
 
   // The method pointer in the frame might be the only path to the method's
   // klass, and the klass needs to be kept alive while executing. The GCs

@@ -1050,10 +1093,19 @@
   bool            _has_appendix;  // true if the call has an appendix
   frame           _fr;
   RegisterMap*    _reg_map;
   int             _arg_size;
   VMRegPair*      _regs;        // VMReg list of arguments
+  BufferedValuesDealiaser* _dealiaser;
+
+  BufferedValuesDealiaser* dealiaser() {
+    if (_dealiaser == NULL) {
+      _dealiaser = Thread::current()->buffered_values_dealiaser();
+      assert(_dealiaser != NULL, "Must not be NULL");
+    }
+    return _dealiaser;
+  }
 
   void set(int size, BasicType type) {
     if (type == T_OBJECT || type == T_ARRAY || type == T_VALUETYPE) handle_oop_offset();
     _offset += size;
   }

@@ -1062,11 +1114,16 @@
     // Extract low order register number from register array.
     // In LP64-land, the high-order bits are valid but unhelpful.
     assert(_offset < _arg_size, "out of bounds");
     VMReg reg = _regs[_offset].first();
     oop *loc = _fr.oopmapreg_to_location(reg, _reg_map);
+    if (!VTBuffer::is_in_vt_buffer(*loc)) {
     _f->do_oop(loc);
+    } else { // Buffered value types case
+      assert((*loc)->is_value(), "Only values can be buffered");
+      dealiaser()->oops_do(_f, *loc);
+    }
   }
 
  public:
   CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
     : SignatureInfo(signature) {

@@ -1077,10 +1134,11 @@
     _has_receiver = has_receiver;
     _has_appendix = has_appendix;
     _fr        = fr;
     _reg_map   = (RegisterMap*)reg_map;
     _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &_arg_size);
+    _dealiaser = NULL;
   }
 
   void oops_do() {
     if (_has_receiver) {
       handle_oop_offset();
< prev index next >