282 283 void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { 284 ((Method*)_method->*meth_act)(_bci); 285 286 // add/remove breakpoint to/from versions of the method that are EMCP. 287 Thread *thread = Thread::current(); 288 instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); 289 Symbol* m_name = _method->name(); 290 Symbol* m_signature = _method->signature(); 291 292 // search previous versions if they exist 293 for (InstanceKlass* pv_node = ikh->previous_versions(); 294 pv_node != NULL; 295 pv_node = pv_node->previous_versions()) { 296 Array<Method*>* methods = pv_node->methods(); 297 298 for (int i = methods->length() - 1; i >= 0; i--) { 299 Method* method = methods->at(i); 300 // Only set breakpoints in running EMCP methods. 301 if (method->is_running_emcp() && 302 method->name() == m_name && 303 method->signature() == m_signature) { 304 RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", 305 meth_act == &Method::set_breakpoint ? "sett" : "clear", 306 method->name()->as_C_string(), 307 method->signature()->as_C_string())); 308 309 (method->*meth_act)(_bci); 310 break; 311 } 312 } 313 } 314 } 315 316 void JvmtiBreakpoint::set() { 317 each_method_version_do(&Method::set_breakpoint); 318 } 319 320 void JvmtiBreakpoint::clear() { 321 each_method_version_do(&Method::clear_breakpoint); 322 } 323 588 } 589 return jvf; 590 } 591 592 // Check that the klass is assignable to a type with the given signature. 593 // Another solution could be to use the function Klass::is_subtype_of(type). 594 // But the type class can be forced to load/initialize eagerly in such a case. 595 // This may cause unexpected consequences like CFLH or class-init JVMTI events. 596 // It is better to avoid such a behavior. 597 bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) { 598 assert(ty_sign != NULL, "type signature must not be NULL"); 599 assert(thread != NULL, "thread must not be NULL"); 600 assert(klass != NULL, "klass must not be NULL"); 601 602 int len = (int) strlen(ty_sign); 603 if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name 604 ty_sign++; 605 len -= 2; 606 } 607 TempNewSymbol ty_sym = SymbolTable::new_symbol(ty_sign, len, thread); 608 if (klass->name() == ty_sym) { 609 return true; 610 } 611 // Compare primary supers 612 int super_depth = klass->super_depth(); 613 int idx; 614 for (idx = 0; idx < super_depth; idx++) { 615 if (klass->primary_super_of_depth(idx)->name() == ty_sym) { 616 return true; 617 } 618 } 619 // Compare secondary supers 620 Array<Klass*>* sec_supers = klass->secondary_supers(); 621 for (idx = 0; idx < sec_supers->length(); idx++) { 622 if (((Klass*) sec_supers->at(idx))->name() == ty_sym) { 623 return true; 624 } 625 } 626 return false; 627 } 628 629 // Checks error conditions: 630 // JVMTI_ERROR_INVALID_SLOT 631 // JVMTI_ERROR_TYPE_MISMATCH 632 // Returns: 'true' - everything is Ok, 'false' - error code 633 634 bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) { 635 Method* method_oop = jvf->method(); 636 if (!method_oop->has_localvariable_table()) { 637 // Just to check index boundaries 638 jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0; 639 if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) { 640 _result = JVMTI_ERROR_INVALID_SLOT; 641 return false; 642 } | 282 283 void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { 284 ((Method*)_method->*meth_act)(_bci); 285 286 // add/remove breakpoint to/from versions of the method that are EMCP. 287 Thread *thread = Thread::current(); 288 instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); 289 Symbol* m_name = _method->name(); 290 Symbol* m_signature = _method->signature(); 291 292 // search previous versions if they exist 293 for (InstanceKlass* pv_node = ikh->previous_versions(); 294 pv_node != NULL; 295 pv_node = pv_node->previous_versions()) { 296 Array<Method*>* methods = pv_node->methods(); 297 298 for (int i = methods->length() - 1; i >= 0; i--) { 299 Method* method = methods->at(i); 300 // Only set breakpoints in running EMCP methods. 301 if (method->is_running_emcp() && 302 method->name()->equals(m_name) && 303 method->signature()->equals(m_signature)) { 304 RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", 305 meth_act == &Method::set_breakpoint ? "sett" : "clear", 306 method->name()->as_C_string(), 307 method->signature()->as_C_string())); 308 309 (method->*meth_act)(_bci); 310 break; 311 } 312 } 313 } 314 } 315 316 void JvmtiBreakpoint::set() { 317 each_method_version_do(&Method::set_breakpoint); 318 } 319 320 void JvmtiBreakpoint::clear() { 321 each_method_version_do(&Method::clear_breakpoint); 322 } 323 588 } 589 return jvf; 590 } 591 592 // Check that the klass is assignable to a type with the given signature. 593 // Another solution could be to use the function Klass::is_subtype_of(type). 594 // But the type class can be forced to load/initialize eagerly in such a case. 595 // This may cause unexpected consequences like CFLH or class-init JVMTI events. 596 // It is better to avoid such a behavior. 597 bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) { 598 assert(ty_sign != NULL, "type signature must not be NULL"); 599 assert(thread != NULL, "thread must not be NULL"); 600 assert(klass != NULL, "klass must not be NULL"); 601 602 int len = (int) strlen(ty_sign); 603 if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name 604 ty_sign++; 605 len -= 2; 606 } 607 TempNewSymbol ty_sym = SymbolTable::new_symbol(ty_sign, len, thread); 608 if (klass->name()->equals(ty_sym)) { 609 return true; 610 } 611 // Compare primary supers 612 int super_depth = klass->super_depth(); 613 int idx; 614 for (idx = 0; idx < super_depth; idx++) { 615 if (klass->primary_super_of_depth(idx)->name()->equals(ty_sym)) { 616 return true; 617 } 618 } 619 // Compare secondary supers 620 Array<Klass*>* sec_supers = klass->secondary_supers(); 621 for (idx = 0; idx < sec_supers->length(); idx++) { 622 if (((Klass*) sec_supers->at(idx))->name()->equals(ty_sym)) { 623 return true; 624 } 625 } 626 return false; 627 } 628 629 // Checks error conditions: 630 // JVMTI_ERROR_INVALID_SLOT 631 // JVMTI_ERROR_TYPE_MISMATCH 632 // Returns: 'true' - everything is Ok, 'false' - error code 633 634 bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) { 635 Method* method_oop = jvf->method(); 636 if (!method_oop->has_localvariable_table()) { 637 // Just to check index boundaries 638 jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0; 639 if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) { 640 _result = JVMTI_ERROR_INVALID_SLOT; 641 return false; 642 } |