< prev index next >

src/hotspot/share/prims/jvmtiImpl.cpp

Print this page




  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/symbolTable.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "interpreter/interpreter.hpp"
  29 #include "interpreter/oopMapCache.hpp"
  30 #include "jvmtifiles/jvmtiEnv.hpp"
  31 #include "logging/log.hpp"
  32 #include "logging/logStream.hpp"
  33 #include "memory/allocation.inline.hpp"
  34 #include "memory/resourceArea.hpp"
  35 #include "oops/instanceKlass.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "prims/jvmtiAgentThread.hpp"
  38 #include "prims/jvmtiEventController.inline.hpp"
  39 #include "prims/jvmtiImpl.hpp"
  40 #include "prims/jvmtiRedefineClasses.hpp"
  41 #include "runtime/atomic.hpp"

  42 #include "runtime/deoptimization.hpp"
  43 #include "runtime/frame.inline.hpp"
  44 #include "runtime/handles.inline.hpp"
  45 #include "runtime/interfaceSupport.inline.hpp"
  46 #include "runtime/javaCalls.hpp"
  47 #include "runtime/os.hpp"
  48 #include "runtime/serviceThread.hpp"
  49 #include "runtime/signature.hpp"
  50 #include "runtime/thread.inline.hpp"
  51 #include "runtime/threadSMR.hpp"
  52 #include "runtime/vframe.hpp"
  53 #include "runtime/vframe_hp.hpp"
  54 #include "runtime/vmOperations.hpp"
  55 #include "utilities/exceptions.hpp"
  56 
  57 //
  58 // class JvmtiAgentThread
  59 //
  60 // JavaThread used to wrap a thread started by an agent
  61 // using the JVMTI method RunAgentThread.


 535 {
 536 }
 537 
 538 // Constructor for object getter
 539 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index)
 540   : _thread(thread)
 541   , _calling_thread(calling_thread)
 542   , _depth(depth)
 543   , _index(index)
 544   , _type(T_OBJECT)
 545   , _jvf(NULL)
 546   , _set(false)
 547   , _result(JVMTI_ERROR_NONE)
 548 {
 549 }
 550 
 551 vframe *VM_GetOrSetLocal::get_vframe() {
 552   if (!_thread->has_last_Java_frame()) {
 553     return NULL;
 554   }
 555   RegisterMap reg_map(_thread);
 556   vframe *vf = _thread->last_java_vframe(&reg_map);
 557   int d = 0;
 558   while ((vf != NULL) && (d < _depth)) {
 559     vf = vf->java_sender();
 560     d++;
 561   }
 562   return vf;
 563 }
 564 
 565 javaVFrame *VM_GetOrSetLocal::get_java_vframe() {
 566   vframe* vf = get_vframe();
 567   if (vf == NULL) {
 568     _result = JVMTI_ERROR_NO_MORE_FRAMES;
 569     return NULL;
 570   }
 571   javaVFrame *jvf = (javaVFrame*)vf;
 572 
 573   if (!vf->is_java_frame()) {
 574     _result = JVMTI_ERROR_OPAQUE_FRAME;
 575     return NULL;


 604       return true;
 605     }
 606   }
 607   // Compare secondary supers
 608   const Array<Klass*>* sec_supers = klass->secondary_supers();
 609   for (idx = 0; idx < sec_supers->length(); idx++) {
 610     if (((Klass*) sec_supers->at(idx))->name() == ty_sym) {
 611       return true;
 612     }
 613   }
 614   return false;
 615 }
 616 
 617 // Checks error conditions:
 618 //   JVMTI_ERROR_INVALID_SLOT
 619 //   JVMTI_ERROR_TYPE_MISMATCH
 620 // Returns: 'true' - everything is Ok, 'false' - error code
 621 
 622 bool VM_GetOrSetLocal::check_slot_type_lvt(javaVFrame* jvf) {
 623   Method* method_oop = jvf->method();










 624   jint num_entries = method_oop->localvariable_table_length();
 625   if (num_entries == 0) {
 626     _result = JVMTI_ERROR_INVALID_SLOT;
 627     return false;       // There are no slots
 628   }
 629   int signature_idx = -1;
 630   int vf_bci = jvf->bci();
 631   LocalVariableTableElement* table = method_oop->localvariable_table_start();
 632   for (int i = 0; i < num_entries; i++) {
 633     int start_bci = table[i].start_bci;
 634     int end_bci = start_bci + table[i].length;
 635 
 636     // Here we assume that locations of LVT entries
 637     // with the same slot number cannot be overlapped
 638     if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) {
 639       signature_idx = (int) table[i].descriptor_cp_index;
 640       break;
 641     }
 642   }
 643   if (signature_idx == -1) {


 704     BasicType extra_slot_type = locals->at(_index + 1)->type();
 705     if (extra_slot_type != T_INT) {
 706       _result = JVMTI_ERROR_INVALID_SLOT;
 707       return false;
 708     }
 709   }
 710   if (_type != slot_type && (_type == T_OBJECT || slot_type != T_INT)) {
 711     _result = JVMTI_ERROR_TYPE_MISMATCH;
 712     return false;
 713   }
 714   return true;
 715 }
 716 
 717 static bool can_be_deoptimized(vframe* vf) {
 718   return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized());
 719 }
 720 
 721 bool VM_GetOrSetLocal::doit_prologue() {
 722   _jvf = get_java_vframe();
 723   NULL_CHECK(_jvf, false);





 724 
 725   Method* method_oop = _jvf->method();
 726   if (method_oop->is_native()) {
 727     if (getting_receiver() && !method_oop->is_static()) {
 728       return true;
 729     } else {
 730       _result = JVMTI_ERROR_OPAQUE_FRAME;
 731       return false;
 732     }
 733   }
 734 
 735   if (!check_slot_type_no_lvt(_jvf)) {
 736     return false;
 737   }
 738   if (method_oop->has_localvariable_table()) {
 739     return check_slot_type_lvt(_jvf);
 740   }
 741   return true;
 742 }
 743 




  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/symbolTable.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "interpreter/interpreter.hpp"
  29 #include "interpreter/oopMapCache.hpp"
  30 #include "jvmtifiles/jvmtiEnv.hpp"
  31 #include "logging/log.hpp"
  32 #include "logging/logStream.hpp"
  33 #include "memory/allocation.inline.hpp"
  34 #include "memory/resourceArea.hpp"
  35 #include "oops/instanceKlass.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "prims/jvmtiAgentThread.hpp"
  38 #include "prims/jvmtiEventController.inline.hpp"
  39 #include "prims/jvmtiImpl.hpp"
  40 #include "prims/jvmtiRedefineClasses.hpp"
  41 #include "runtime/atomic.hpp"
  42 #include "runtime/continuation.hpp"
  43 #include "runtime/deoptimization.hpp"
  44 #include "runtime/frame.inline.hpp"
  45 #include "runtime/handles.inline.hpp"
  46 #include "runtime/interfaceSupport.inline.hpp"
  47 #include "runtime/javaCalls.hpp"
  48 #include "runtime/os.hpp"
  49 #include "runtime/serviceThread.hpp"
  50 #include "runtime/signature.hpp"
  51 #include "runtime/thread.inline.hpp"
  52 #include "runtime/threadSMR.hpp"
  53 #include "runtime/vframe.hpp"
  54 #include "runtime/vframe_hp.hpp"
  55 #include "runtime/vmOperations.hpp"
  56 #include "utilities/exceptions.hpp"
  57 
  58 //
  59 // class JvmtiAgentThread
  60 //
  61 // JavaThread used to wrap a thread started by an agent
  62 // using the JVMTI method RunAgentThread.


 536 {
 537 }
 538 
 539 // Constructor for object getter
 540 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index)
 541   : _thread(thread)
 542   , _calling_thread(calling_thread)
 543   , _depth(depth)
 544   , _index(index)
 545   , _type(T_OBJECT)
 546   , _jvf(NULL)
 547   , _set(false)
 548   , _result(JVMTI_ERROR_NONE)
 549 {
 550 }
 551 
 552 vframe *VM_GetOrSetLocal::get_vframe() {
 553   if (!_thread->has_last_Java_frame()) {
 554     return NULL;
 555   }
 556   RegisterMap reg_map(_thread, true, true);
 557   vframe *vf = _thread->last_java_vframe(&reg_map);
 558   int d = 0;
 559   while ((vf != NULL) && (d < _depth)) {
 560     vf = vf->java_sender();
 561     d++;
 562   }
 563   return vf;
 564 }
 565 
 566 javaVFrame *VM_GetOrSetLocal::get_java_vframe() {
 567   vframe* vf = get_vframe();
 568   if (vf == NULL) {
 569     _result = JVMTI_ERROR_NO_MORE_FRAMES;
 570     return NULL;
 571   }
 572   javaVFrame *jvf = (javaVFrame*)vf;
 573 
 574   if (!vf->is_java_frame()) {
 575     _result = JVMTI_ERROR_OPAQUE_FRAME;
 576     return NULL;


 605       return true;
 606     }
 607   }
 608   // Compare secondary supers
 609   const Array<Klass*>* sec_supers = klass->secondary_supers();
 610   for (idx = 0; idx < sec_supers->length(); idx++) {
 611     if (((Klass*) sec_supers->at(idx))->name() == ty_sym) {
 612       return true;
 613     }
 614   }
 615   return false;
 616 }
 617 
 618 // Checks error conditions:
 619 //   JVMTI_ERROR_INVALID_SLOT
 620 //   JVMTI_ERROR_TYPE_MISMATCH
 621 // Returns: 'true' - everything is Ok, 'false' - error code
 622 
 623 bool VM_GetOrSetLocal::check_slot_type_lvt(javaVFrame* jvf) {
 624   Method* method_oop = jvf->method();
 625   if (!method_oop->has_localvariable_table()) {
 626     // Just to check index boundaries
 627     jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0;
 628     if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) {
 629       _result = JVMTI_ERROR_INVALID_SLOT;
 630       return false;
 631     }
 632     return true;
 633   }
 634 
 635   jint num_entries = method_oop->localvariable_table_length();
 636   if (num_entries == 0) {
 637     _result = JVMTI_ERROR_INVALID_SLOT;
 638     return false;       // There are no slots
 639   }
 640   int signature_idx = -1;
 641   int vf_bci = jvf->bci();
 642   LocalVariableTableElement* table = method_oop->localvariable_table_start();
 643   for (int i = 0; i < num_entries; i++) {
 644     int start_bci = table[i].start_bci;
 645     int end_bci = start_bci + table[i].length;
 646 
 647     // Here we assume that locations of LVT entries
 648     // with the same slot number cannot be overlapped
 649     if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) {
 650       signature_idx = (int) table[i].descriptor_cp_index;
 651       break;
 652     }
 653   }
 654   if (signature_idx == -1) {


 715     BasicType extra_slot_type = locals->at(_index + 1)->type();
 716     if (extra_slot_type != T_INT) {
 717       _result = JVMTI_ERROR_INVALID_SLOT;
 718       return false;
 719     }
 720   }
 721   if (_type != slot_type && (_type == T_OBJECT || slot_type != T_INT)) {
 722     _result = JVMTI_ERROR_TYPE_MISMATCH;
 723     return false;
 724   }
 725   return true;
 726 }
 727 
 728 static bool can_be_deoptimized(vframe* vf) {
 729   return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized());
 730 }
 731 
 732 bool VM_GetOrSetLocal::doit_prologue() {
 733   _jvf = get_java_vframe();
 734   NULL_CHECK(_jvf, false);
 735 
 736   if (_set && Continuation::is_frame_in_continuation(_jvf->thread(), _jvf->fr())) {
 737     _result = JVMTI_ERROR_OPAQUE_FRAME; // deferred locals currently unsupported in continuations
 738     return false;
 739   }
 740 
 741   Method* method_oop = _jvf->method();
 742   if (method_oop->is_native()) {
 743     if (getting_receiver() && !method_oop->is_static()) {
 744       return true;
 745     } else {
 746       _result = JVMTI_ERROR_OPAQUE_FRAME;
 747       return false;
 748     }
 749   }
 750 
 751   if (!check_slot_type_no_lvt(_jvf)) {
 752     return false;
 753   }
 754   if (method_oop->has_localvariable_table()) {
 755     return check_slot_type_lvt(_jvf);
 756   }
 757   return true;
 758 }
 759 


< prev index next >