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_identity_hash(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 CHeapObj<mtCompiler> { 530 private: 531 int _args_count; 532 uintptr_t _argument_hash[Dependencies::max_arg_count]; 533 DependencySignature* _parent; 534 DependencySignature* _left; 535 DependencySignature* _right; 536 DependencySignature* _next; 537 538 public: 539 DependencySignature(DependencySignature* sig) { 540 _parent = _left = _right = _next = NULL; 541 _args_count = sig->args_count(); 542 for (int i = 0; i < _args_count; i++) { 543 _argument_hash[i] = sig->_argument_hash[i]; 544 } 545 } 546 547 DependencySignature(Dependencies::DepStream* dep) { 548 _parent = _left = _right = _next = NULL; 549 _args_count = dep->argument_count(); 550 for (int i = 0; i < _args_count; i++) { 551 _argument_hash[i] = dep->get_identity_hash(i); 552 } 553 } 554 555 int args_count() const { return _args_count; } 556 uintptr_t key() const { return (_args_count == 2) ?_argument_hash[1] : _argument_hash[0]; } 557 uintptr_t arg(int idx) const { return _argument_hash[idx]; } 558 559 DependencySignature* left() const { return _left; } 560 DependencySignature* right() const { return _right; } 561 DependencySignature* next() const { return _next; } 562 563 void set_parent(DependencySignature* sig) { _parent = sig; } 564 void set_left(DependencySignature* sig) { _left = sig; } 565 void set_right(DependencySignature* sig) { _right = sig; } 566 void set_next (DependencySignature* sig) { _next = sig; } 567 }; 568 569 class DependencySignatureBuffer : public CHeapObj<mtCompiler> { 570 private: 571 Dependencies::DepType _type; 572 DependencySignature* _root; 573 574 DependencySignature* tree_search(DependencySignature* x, uintptr_t key); 575 576 public: 577 DependencySignatureBuffer(Dependencies::DepType type); 578 579 Dependencies::DepType type() const { return _type; } 580 static DependencySignatureBuffer* buffer(GrowableArray<DependencySignatureBuffer*>* signature_buffers, Dependencies::DepType type); 581 bool contains(DependencySignature* sig); 582 void add(DependencySignature* to_add); 583 }; 584 585 // Every particular DepChange is a sub-class of this class. 586 class DepChange : public StackObj { 587 public: 588 // What kind of DepChange is this? 589 virtual bool is_klass_change() const { return false; } 590 virtual bool is_call_site_change() const { return false; } 591 592 // Subclass casting with assertions. 593 KlassDepChange* as_klass_change() { 594 assert(is_klass_change(), "bad cast"); 595 return (KlassDepChange*) this; 596 } 597 CallSiteDepChange* as_call_site_change() { 598 assert(is_call_site_change(), "bad cast"); 599 return (CallSiteDepChange*) this; 600 } 601 602 void print(); 603 |