463 464 public: 465 DepStream(Dependencies* deps) 466 : _deps(deps), 467 _code(NULL), 468 _bytes(deps->content_bytes()) 469 { 470 initial_asserts(deps->size_in_bytes()); 471 } 472 DepStream(nmethod* code) 473 : _deps(NULL), 474 _code(code), 475 _bytes(code->dependencies_begin()) 476 { 477 initial_asserts(code->dependencies_size()); 478 } 479 480 bool next(); 481 482 DepType type() { return _type; } 483 int argument_count() { return dep_args(type()); } 484 int argument_index(int i) { assert(0 <= i && i < argument_count(), "oob"); 485 return _xi[i]; } 486 Metadata* argument(int i); // => recorded_oop_at(argument_index(i)) 487 oop argument_oop(int i); // => recorded_oop_at(argument_index(i)) 488 Klass* context_type(); 489 490 bool is_klass_type() { return Dependencies::is_klass_type(type()); } 491 492 Method* method_argument(int i) { 493 Metadata* x = argument(i); 494 assert(x->is_method(), "type"); 495 return (Method*) x; 496 } 497 Klass* type_argument(int i) { 498 Metadata* x = argument(i); 499 assert(x->is_klass(), "type"); 500 return (Klass*) x; 501 } 502 505 Klass* result = check_klass_dependency(NULL); 506 if (result != NULL) return result; 507 return check_call_site_dependency(NULL); 508 } 509 510 // A lighter version: Checks only around recent changes in a class 511 // hierarchy. (See Universe::flush_dependents_on.) 512 Klass* spot_check_dependency_at(DepChange& changes); 513 514 // Log the current dependency to xtty or compilation log. 515 void log_dependency(Klass* witness = NULL); 516 517 // Print the current dependency to tty. 518 void print_dependency(Klass* witness = NULL, bool verbose = false); 519 }; 520 friend class Dependencies::DepStream; 521 522 static void print_statistics() PRODUCT_RETURN; 523 }; 524 525 526 // Every particular DepChange is a sub-class of this class. 527 class DepChange : public StackObj { 528 public: 529 // What kind of DepChange is this? 530 virtual bool is_klass_change() const { return false; } 531 virtual bool is_call_site_change() const { return false; } 532 533 // Subclass casting with assertions. 534 KlassDepChange* as_klass_change() { 535 assert(is_klass_change(), "bad cast"); 536 return (KlassDepChange*) this; 537 } 538 CallSiteDepChange* as_call_site_change() { 539 assert(is_call_site_change(), "bad cast"); 540 return (CallSiteDepChange*) this; 541 } 542 543 void print(); 544 | 463 464 public: 465 DepStream(Dependencies* deps) 466 : _deps(deps), 467 _code(NULL), 468 _bytes(deps->content_bytes()) 469 { 470 initial_asserts(deps->size_in_bytes()); 471 } 472 DepStream(nmethod* code) 473 : _deps(NULL), 474 _code(code), 475 _bytes(code->dependencies_begin()) 476 { 477 initial_asserts(code->dependencies_size()); 478 } 479 480 bool next(); 481 482 DepType type() { return _type; } 483 bool has_oop_argument() { return type() == call_site_target_value; } 484 uintptr_t get_identifier(int i); 485 486 int argument_count() { return dep_args(type()); } 487 int argument_index(int i) { assert(0 <= i && i < argument_count(), "oob"); 488 return _xi[i]; } 489 Metadata* argument(int i); // => recorded_oop_at(argument_index(i)) 490 oop argument_oop(int i); // => recorded_oop_at(argument_index(i)) 491 Klass* context_type(); 492 493 bool is_klass_type() { return Dependencies::is_klass_type(type()); } 494 495 Method* method_argument(int i) { 496 Metadata* x = argument(i); 497 assert(x->is_method(), "type"); 498 return (Method*) x; 499 } 500 Klass* type_argument(int i) { 501 Metadata* x = argument(i); 502 assert(x->is_klass(), "type"); 503 return (Klass*) x; 504 } 505 508 Klass* result = check_klass_dependency(NULL); 509 if (result != NULL) return result; 510 return check_call_site_dependency(NULL); 511 } 512 513 // A lighter version: Checks only around recent changes in a class 514 // hierarchy. (See Universe::flush_dependents_on.) 515 Klass* spot_check_dependency_at(DepChange& changes); 516 517 // Log the current dependency to xtty or compilation log. 518 void log_dependency(Klass* witness = NULL); 519 520 // Print the current dependency to tty. 521 void print_dependency(Klass* witness = NULL, bool verbose = false); 522 }; 523 friend class Dependencies::DepStream; 524 525 static void print_statistics() PRODUCT_RETURN; 526 }; 527 528 529 class DependencySignature : public ResourceObj { 530 private: 531 int _args_count; 532 uintptr_t _argument_hash[Dependencies::max_arg_count]; 533 Dependencies::DepType _type; 534 535 536 public: 537 DependencySignature(Dependencies::DepStream& dep) { 538 _args_count = dep.argument_count(); 539 _type = dep.type(); 540 for (int i = 0; i < _args_count; i++) { 541 _argument_hash[i] = dep.get_identifier(i); 542 } 543 } 544 545 bool equals(const DependencySignature& sig) const; 546 547 int args_count() const { return _args_count; } 548 uintptr_t arg(int idx) const { return _argument_hash[idx]; } 549 Dependencies::DepType type() const { return _type; } 550 }; 551 552 class DependencySignatureBuffer : public StackObj { 553 private: 554 GrowableArray<DependencySignature*>** _signatures; 555 556 public: 557 DependencySignatureBuffer(); 558 bool add_if_missing(const DependencySignature& sig); 559 }; 560 561 // Every particular DepChange is a sub-class of this class. 562 class DepChange : public StackObj { 563 public: 564 // What kind of DepChange is this? 565 virtual bool is_klass_change() const { return false; } 566 virtual bool is_call_site_change() const { return false; } 567 568 // Subclass casting with assertions. 569 KlassDepChange* as_klass_change() { 570 assert(is_klass_change(), "bad cast"); 571 return (KlassDepChange*) this; 572 } 573 CallSiteDepChange* as_call_site_change() { 574 assert(is_call_site_change(), "bad cast"); 575 return (CallSiteDepChange*) this; 576 } 577 578 void print(); 579 |