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 { 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(DependencySignature* sig) { 538 _args_count = sig->args_count(); 539 _type = sig->type(); 540 for (int i = 0; i < _args_count; i++) { 541 _argument_hash[i] = sig->_argument_hash[i]; 542 } 543 } 544 545 DependencySignature(Dependencies::DepStream& dep) { 546 _args_count = dep.argument_count(); 547 _type = dep.type(); 548 for (int i = 0; i < _args_count; i++) { 549 _argument_hash[i] = dep.get_identifier(i); 550 } 551 } 552 553 bool equals(const DependencySignature& sig) const; 554 void* operator new(size_t size) throw(); 555 556 int args_count() const { return _args_count; } 557 uintptr_t arg(int idx) const { return _argument_hash[idx]; } 558 Dependencies::DepType type() const { return _type; } 559 }; 560 561 class DependencySignatureBuffer : public StackObj { 562 private: 563 GrowableArray<DependencySignature*>** _signatures; 564 565 public: 566 DependencySignatureBuffer(); 567 bool add_if_missing(const DependencySignature& sig); 568 }; 569 570 // Every particular DepChange is a sub-class of this class. 571 class DepChange : public StackObj { 572 public: 573 // What kind of DepChange is this? 574 virtual bool is_klass_change() const { return false; } 575 virtual bool is_call_site_change() const { return false; } 576 577 // Subclass casting with assertions. 578 KlassDepChange* as_klass_change() { 579 assert(is_klass_change(), "bad cast"); 580 return (KlassDepChange*) this; 581 } 582 CallSiteDepChange* as_call_site_change() { 583 assert(is_call_site_change(), "bad cast"); 584 return (CallSiteDepChange*) this; 585 } 586 587 void print(); 588 |