< prev index next >

src/share/vm/opto/machnode.cpp

Print this page




 176       return 0;                 // mis-matched operands
 177   return 1;                     // match
 178 }
 179 
 180 // Return an equivalent instruction using memory for cisc_operand position
 181 MachNode *MachNode::cisc_version(int offset) {
 182   ShouldNotCallThis();
 183   return NULL;
 184 }
 185 
 186 void MachNode::use_cisc_RegMask() {
 187   ShouldNotReachHere();
 188 }
 189 
 190 
 191 //-----------------------------in_RegMask--------------------------------------
 192 const RegMask &MachNode::in_RegMask( uint idx ) const {
 193   uint numopnds = num_opnds();        // Virtual call for number of operands
 194   uint skipped   = oper_input_base(); // Sum of leaves skipped so far
 195   if( idx < skipped ) {
 196     assert( ideal_Opcode() == Op_AddP, "expected base ptr here" );
 197     assert( idx == 1, "expected base ptr here" );
 198     // debug info can be anywhere
 199     return *Compile::current()->matcher()->idealreg2spillmask[Op_RegP];
 200   }
 201   uint opcnt     = 1;                 // First operand
 202   uint num_edges = _opnds[1]->num_edges(); // leaves for first operand
 203   while( idx >= skipped+num_edges ) {
 204     skipped += num_edges;
 205     opcnt++;                          // Bump operand count
 206     assert( opcnt < numopnds, "Accessing non-existent operand" );
 207     num_edges = _opnds[opcnt]->num_edges(); // leaves for next operand
 208   }
 209 
 210   const RegMask *rm = cisc_RegMask();
 211   if( rm == NULL || (int)opcnt != cisc_operand() ) {
 212     rm = _opnds[opcnt]->in_RegMask(idx-skipped);
 213   }
 214   return *rm;
 215 }
 216 
 217 //-----------------------------memory_inputs--------------------------------
 218 const MachOper*  MachNode::memory_inputs(Node* &base, Node* &index) const {
 219   const MachOper* oper = memory_operand();


 427   ShouldNotCallThis();
 428 }
 429 
 430 //------------------------------rematerialize----------------------------------
 431 bool MachNode::rematerialize() const {
 432   // Temps are always rematerializable
 433   if (is_MachTemp()) return true;
 434 
 435   uint r = rule();              // Match rule
 436   if (r <  Matcher::_begin_rematerialize ||
 437       r >= Matcher::_end_rematerialize) {
 438     return false;
 439   }
 440 
 441   // For 2-address instructions, the input live range is also the output
 442   // live range. Remateralizing does not make progress on the that live range.
 443   if (two_adr()) return false;
 444 
 445   // Check for rematerializing float constants, or not
 446   if (!Matcher::rematerialize_float_constants) {
 447     int op = ideal_Opcode();
 448     if (op == Op_ConF || op == Op_ConD) {
 449       return false;
 450     }
 451   }
 452 
 453   // Defining flags - can't spill these! Must remateralize.
 454   if (ideal_reg() == Op_RegFlags) {
 455     return true;
 456   }
 457 
 458   // Stretching lots of inputs - don't do it.
 459   if (req() > 2) {
 460     return false;
 461   }
 462 
 463   if (req() == 2 && in(1) && in(1)->ideal_reg() == Op_RegFlags) {
 464     // In(1) will be rematerialized, too.
 465     // Stretching lots of inputs - don't do it.
 466     if (in(1)->req() > 2) {
 467       return false;
 468     }
 469   }
 470 
 471   // Don't remateralize somebody with bound inputs - it stretches a
 472   // fixed register lifetime.
 473   uint idx = oper_input_base();
 474   if (req() > idx) {
 475     const RegMask &rm = in_RegMask(idx);
 476     if (rm.is_bound(ideal_reg())) {
 477       return false;
 478     }
 479   }
 480 
 481   return true;
 482 }
 483 


 550 }
 551 #endif
 552 
 553 void MachNullCheckNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 554   // only emits entries in the null-pointer exception handler table
 555 }
 556 void MachNullCheckNode::label_set(Label* label, uint block_num) {
 557   // Nothing to emit
 558 }
 559 void MachNullCheckNode::save_label( Label** label, uint* block_num ) {
 560   // Nothing to emit
 561 }
 562 
 563 const RegMask &MachNullCheckNode::in_RegMask( uint idx ) const {
 564   if( idx == 0 ) return RegMask::Empty;
 565   else return in(1)->as_Mach()->out_RegMask();
 566 }
 567 
 568 //=============================================================================
 569 const Type *MachProjNode::bottom_type() const {
 570   if( _ideal_reg == fat_proj ) return Type::BOTTOM;
 571   // Try the normal mechanism first
 572   const Type *t = in(0)->bottom_type();
 573   if( t->base() == Type::Tuple ) {
 574     const TypeTuple *tt = t->is_tuple();
 575     if (_con < tt->cnt())
 576       return tt->field_at(_con);
 577   }
 578   // Else use generic type from ideal register set
 579   assert((uint)_ideal_reg < (uint)_last_machine_leaf && Type::mreg2type[_ideal_reg], "in bounds");
 580   return Type::mreg2type[_ideal_reg];
 581 }
 582 
 583 const TypePtr *MachProjNode::adr_type() const {
 584   if (bottom_type() == Type::MEMORY) {
 585     // in(0) might be a narrow MemBar; otherwise we will report TypePtr::BOTTOM
 586     Node* ctrl = in(0);
 587     if (ctrl == NULL)  return NULL; // node is dead
 588     const TypePtr* adr_type = ctrl->adr_type();
 589     #ifdef ASSERT
 590     if (!is_error_reported() && !Node::in_dump())
 591       assert(adr_type != NULL, "source must have adr_type");
 592     #endif
 593     return adr_type;
 594   }
 595   assert(bottom_type()->base() != Type::Memory, "no other memories?");
 596   return NULL;
 597 }
 598 
 599 #ifndef PRODUCT
 600 void MachProjNode::dump_spec(outputStream *st) const {
 601   ProjNode::dump_spec(st);
 602   switch (_ideal_reg) {
 603   case unmatched_proj:  st->print("/unmatched");                           break;
 604   case fat_proj:        st->print("/fat"); if (WizardMode) _rout.dump(st); break;




 605   }
 606 }
 607 #endif
 608 
 609 //=============================================================================
 610 #ifndef PRODUCT
 611 void MachIfNode::dump_spec(outputStream *st) const {
 612   st->print("P=%f, C=%f",_prob, _fcnt);
 613 }
 614 #endif
 615 
 616 //=============================================================================
 617 uint MachReturnNode::size_of() const { return sizeof(*this); }
 618 
 619 //------------------------------Registers--------------------------------------
 620 const RegMask &MachReturnNode::in_RegMask( uint idx ) const {
 621   return _in_rms[idx];
 622 }
 623 
 624 const TypePtr *MachReturnNode::adr_type() const {
 625   // most returns and calls are assumed to consume & modify all of memory
 626   // the matcher will copy non-wide adr_types from ideal originals
 627   return _adr_type;
 628 }
 629 
 630 //=============================================================================
 631 const Type *MachSafePointNode::bottom_type() const {  return TypeTuple::MEMBAR; }
 632 
 633 //------------------------------Registers--------------------------------------
 634 const RegMask &MachSafePointNode::in_RegMask( uint idx ) const {
 635   // Values in the domain use the users calling convention, embodied in the
 636   // _in_rms array of RegMasks.
 637   if( idx < TypeFunc::Parms ) return _in_rms[idx];
 638 
 639   if (SafePointNode::needs_polling_address_input() &&
 640       idx == TypeFunc::Parms &&
 641       ideal_Opcode() == Op_SafePoint) {
 642     return MachNode::in_RegMask(idx);
 643   }
 644 
 645   // Values outside the domain represent debug info
 646   return *Compile::current()->matcher()->idealreg2spillmask[in(idx)->ideal_reg()];
 647 }
 648 
 649 
 650 //=============================================================================
 651 
 652 uint MachCallNode::cmp( const Node &n ) const
 653 { return _tf == ((MachCallNode&)n)._tf; }
 654 const Type *MachCallNode::bottom_type() const { return tf()->range(); }
 655 const Type* MachCallNode::Value(PhaseGVN* phase) const { return tf()->range(); }
 656 
 657 #ifndef PRODUCT
 658 void MachCallNode::dump_spec(outputStream *st) const {
 659   st->print("# ");
 660   if (tf() != NULL)  tf()->dump_on(st);
 661   if (_cnt != COUNT_UNKNOWN)  st->print(" C=%f",_cnt);
 662   if (jvms() != NULL)  jvms()->dump_spec(st);
 663 }
 664 #endif
 665 
 666 bool MachCallNode::return_value_is_used() const {


 683 // Similar to cousin class CallNode::returns_pointer
 684 // Because this is used in deoptimization, we want the type info, not the data
 685 // flow info; the interpreter will "use" things that are dead to the optimizer.
 686 bool MachCallNode::returns_pointer() const {
 687   const TypeTuple *r = tf()->range();
 688   return (r->cnt() > TypeFunc::Parms &&
 689           r->field_at(TypeFunc::Parms)->isa_ptr());
 690 }
 691 
 692 //------------------------------Registers--------------------------------------
 693 const RegMask &MachCallNode::in_RegMask(uint idx) const {
 694   // Values in the domain use the users calling convention, embodied in the
 695   // _in_rms array of RegMasks.
 696   if (idx < tf()->domain()->cnt()) {
 697     return _in_rms[idx];
 698   }
 699   if (idx == mach_constant_base_node_input()) {
 700     return MachConstantBaseNode::static_out_RegMask();
 701   }
 702   // Values outside the domain represent debug info
 703   return *Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()];
 704 }
 705 
 706 //=============================================================================
 707 uint MachCallJavaNode::size_of() const { return sizeof(*this); }
 708 uint MachCallJavaNode::cmp( const Node &n ) const {
 709   MachCallJavaNode &call = (MachCallJavaNode&)n;
 710   return MachCallNode::cmp(call) && _method->equals(call._method) &&
 711          _override_symbolic_info == call._override_symbolic_info;
 712 }
 713 #ifndef PRODUCT
 714 void MachCallJavaNode::dump_spec(outputStream *st) const {
 715   if (_method_handle_invoke)
 716     st->print("MethodHandle ");
 717   if (_method) {
 718     _method->print_short_name(st);
 719     st->print(" ");
 720   }
 721   MachCallNode::dump_spec(st);
 722 }
 723 #endif
 724 
 725 //------------------------------Registers--------------------------------------
 726 const RegMask &MachCallJavaNode::in_RegMask(uint idx) const {
 727   // Values in the domain use the users calling convention, embodied in the
 728   // _in_rms array of RegMasks.
 729   if (idx < tf()->domain()->cnt()) {
 730     return _in_rms[idx];
 731   }
 732   if (idx == mach_constant_base_node_input()) {
 733     return MachConstantBaseNode::static_out_RegMask();
 734   }
 735   // Values outside the domain represent debug info
 736   Matcher* m = Compile::current()->matcher();
 737   // If this call is a MethodHandle invoke we have to use a different
 738   // debugmask which does not include the register we use to save the
 739   // SP over MH invokes.
 740   RegMask** debugmask = _method_handle_invoke ? m->idealreg2mhdebugmask : m->idealreg2debugmask;
 741   return *debugmask[in(idx)->ideal_reg()];
 742 }
 743 
 744 //=============================================================================
 745 uint MachCallStaticJavaNode::size_of() const { return sizeof(*this); }
 746 uint MachCallStaticJavaNode::cmp( const Node &n ) const {
 747   MachCallStaticJavaNode &call = (MachCallStaticJavaNode&)n;
 748   return MachCallJavaNode::cmp(call) && _name == call._name;
 749 }
 750 
 751 //----------------------------uncommon_trap_request----------------------------
 752 // If this is an uncommon trap, return the request code, else zero.
 753 int MachCallStaticJavaNode::uncommon_trap_request() const {
 754   if (_name != NULL && !strcmp(_name, "uncommon_trap")) {
 755     return CallStaticJavaNode::extract_uncommon_trap_request(this);
 756   }
 757   return 0;
 758 }
 759 
 760 #ifndef PRODUCT
 761 // Helper for summarizing uncommon_trap arguments.




 176       return 0;                 // mis-matched operands
 177   return 1;                     // match
 178 }
 179 
 180 // Return an equivalent instruction using memory for cisc_operand position
 181 MachNode *MachNode::cisc_version(int offset) {
 182   ShouldNotCallThis();
 183   return NULL;
 184 }
 185 
 186 void MachNode::use_cisc_RegMask() {
 187   ShouldNotReachHere();
 188 }
 189 
 190 
 191 //-----------------------------in_RegMask--------------------------------------
 192 const RegMask &MachNode::in_RegMask( uint idx ) const {
 193   uint numopnds = num_opnds();        // Virtual call for number of operands
 194   uint skipped   = oper_input_base(); // Sum of leaves skipped so far
 195   if( idx < skipped ) {
 196     assert( ideal_Opcode() == Opcodes::Op_AddP, "expected base ptr here" );
 197     assert( idx == 1, "expected base ptr here" );
 198     // debug info can be anywhere
 199     return *Compile::current()->matcher()->idealreg2spillmask[static_cast<uint>(Opcodes::Op_RegP)];
 200   }
 201   uint opcnt     = 1;                 // First operand
 202   uint num_edges = _opnds[1]->num_edges(); // leaves for first operand
 203   while( idx >= skipped+num_edges ) {
 204     skipped += num_edges;
 205     opcnt++;                          // Bump operand count
 206     assert( opcnt < numopnds, "Accessing non-existent operand" );
 207     num_edges = _opnds[opcnt]->num_edges(); // leaves for next operand
 208   }
 209 
 210   const RegMask *rm = cisc_RegMask();
 211   if( rm == NULL || (int)opcnt != cisc_operand() ) {
 212     rm = _opnds[opcnt]->in_RegMask(idx-skipped);
 213   }
 214   return *rm;
 215 }
 216 
 217 //-----------------------------memory_inputs--------------------------------
 218 const MachOper*  MachNode::memory_inputs(Node* &base, Node* &index) const {
 219   const MachOper* oper = memory_operand();


 427   ShouldNotCallThis();
 428 }
 429 
 430 //------------------------------rematerialize----------------------------------
 431 bool MachNode::rematerialize() const {
 432   // Temps are always rematerializable
 433   if (is_MachTemp()) return true;
 434 
 435   uint r = rule();              // Match rule
 436   if (r <  Matcher::_begin_rematerialize ||
 437       r >= Matcher::_end_rematerialize) {
 438     return false;
 439   }
 440 
 441   // For 2-address instructions, the input live range is also the output
 442   // live range. Remateralizing does not make progress on the that live range.
 443   if (two_adr()) return false;
 444 
 445   // Check for rematerializing float constants, or not
 446   if (!Matcher::rematerialize_float_constants) {
 447     Opcodes op = ideal_Opcode();
 448     if (op == Opcodes::Op_ConF || op == Opcodes::Op_ConD) {
 449       return false;
 450     }
 451   }
 452 
 453   // Defining flags - can't spill these! Must remateralize.
 454   if (ideal_reg() == Opcodes::Op_RegFlags) {
 455     return true;
 456   }
 457 
 458   // Stretching lots of inputs - don't do it.
 459   if (req() > 2) {
 460     return false;
 461   }
 462 
 463   if (req() == 2 && in(1) && in(1)->ideal_reg() == Opcodes::Op_RegFlags) {
 464     // In(1) will be rematerialized, too.
 465     // Stretching lots of inputs - don't do it.
 466     if (in(1)->req() > 2) {
 467       return false;
 468     }
 469   }
 470 
 471   // Don't remateralize somebody with bound inputs - it stretches a
 472   // fixed register lifetime.
 473   uint idx = oper_input_base();
 474   if (req() > idx) {
 475     const RegMask &rm = in_RegMask(idx);
 476     if (rm.is_bound(ideal_reg())) {
 477       return false;
 478     }
 479   }
 480 
 481   return true;
 482 }
 483 


 550 }
 551 #endif
 552 
 553 void MachNullCheckNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 554   // only emits entries in the null-pointer exception handler table
 555 }
 556 void MachNullCheckNode::label_set(Label* label, uint block_num) {
 557   // Nothing to emit
 558 }
 559 void MachNullCheckNode::save_label( Label** label, uint* block_num ) {
 560   // Nothing to emit
 561 }
 562 
 563 const RegMask &MachNullCheckNode::in_RegMask( uint idx ) const {
 564   if( idx == 0 ) return RegMask::Empty;
 565   else return in(1)->as_Mach()->out_RegMask();
 566 }
 567 
 568 //=============================================================================
 569 const Type *MachProjNode::bottom_type() const {
 570   if( _ideal_reg == static_cast<Opcodes>(MachProjNode::projType::fat_proj) ) return Type::BOTTOM;
 571   // Try the normal mechanism first
 572   const Type *t = in(0)->bottom_type();
 573   if( t->base() == Type::Tuple ) {
 574     const TypeTuple *tt = t->is_tuple();
 575     if (_con < tt->cnt())
 576       return tt->field_at(_con);
 577   }
 578   // Else use generic type from ideal register set
 579   assert(_ideal_reg < Opcodes::_last_machine_leaf && Type::mreg2type[static_cast<uint>(_ideal_reg)], "in bounds");
 580   return Type::mreg2type[static_cast<uint>(_ideal_reg)];
 581 }
 582 
 583 const TypePtr *MachProjNode::adr_type() const {
 584   if (bottom_type() == Type::MEMORY) {
 585     // in(0) might be a narrow MemBar; otherwise we will report TypePtr::BOTTOM
 586     Node* ctrl = in(0);
 587     if (ctrl == NULL)  return NULL; // node is dead
 588     const TypePtr* adr_type = ctrl->adr_type();
 589     #ifdef ASSERT
 590     if (!is_error_reported() && !Node::in_dump())
 591       assert(adr_type != NULL, "source must have adr_type");
 592     #endif
 593     return adr_type;
 594   }
 595   assert(bottom_type()->base() != Type::Memory, "no other memories?");
 596   return NULL;
 597 }
 598 
 599 #ifndef PRODUCT
 600 void MachProjNode::dump_spec(outputStream *st) const {
 601   ProjNode::dump_spec(st);
 602   switch (static_cast<MachProjNode::projType>(_ideal_reg)) {
 603   case MachProjNode::projType::unmatched_proj:
 604     st->print("/unmatched");
 605     break;
 606   case MachProjNode::projType::fat_proj:
 607     st->print("/fat"); if (WizardMode) _rout.dump(st);
 608     break;
 609   }
 610 }
 611 #endif
 612 
 613 //=============================================================================
 614 #ifndef PRODUCT
 615 void MachIfNode::dump_spec(outputStream *st) const {
 616   st->print("P=%f, C=%f",_prob, _fcnt);
 617 }
 618 #endif
 619 
 620 //=============================================================================
 621 uint MachReturnNode::size_of() const { return sizeof(*this); }
 622 
 623 //------------------------------Registers--------------------------------------
 624 const RegMask &MachReturnNode::in_RegMask( uint idx ) const {
 625   return _in_rms[idx];
 626 }
 627 
 628 const TypePtr *MachReturnNode::adr_type() const {
 629   // most returns and calls are assumed to consume & modify all of memory
 630   // the matcher will copy non-wide adr_types from ideal originals
 631   return _adr_type;
 632 }
 633 
 634 //=============================================================================
 635 const Type *MachSafePointNode::bottom_type() const {  return TypeTuple::MEMBAR; }
 636 
 637 //------------------------------Registers--------------------------------------
 638 const RegMask &MachSafePointNode::in_RegMask( uint idx ) const {
 639   // Values in the domain use the users calling convention, embodied in the
 640   // _in_rms array of RegMasks.
 641   if( idx < TypeFunc::Parms ) return _in_rms[idx];
 642 
 643   if (SafePointNode::needs_polling_address_input() &&
 644       idx == TypeFunc::Parms &&
 645       ideal_Opcode() == Opcodes::Op_SafePoint) {
 646     return MachNode::in_RegMask(idx);
 647   }
 648 
 649   // Values outside the domain represent debug info
 650   return *Compile::current()->matcher()->idealreg2spillmask[static_cast<uint>(in(idx)->ideal_reg())];
 651 }
 652 
 653 
 654 //=============================================================================
 655 
 656 uint MachCallNode::cmp( const Node &n ) const
 657 { return _tf == ((MachCallNode&)n)._tf; }
 658 const Type *MachCallNode::bottom_type() const { return tf()->range(); }
 659 const Type* MachCallNode::Value(PhaseGVN* phase) const { return tf()->range(); }
 660 
 661 #ifndef PRODUCT
 662 void MachCallNode::dump_spec(outputStream *st) const {
 663   st->print("# ");
 664   if (tf() != NULL)  tf()->dump_on(st);
 665   if (_cnt != COUNT_UNKNOWN)  st->print(" C=%f",_cnt);
 666   if (jvms() != NULL)  jvms()->dump_spec(st);
 667 }
 668 #endif
 669 
 670 bool MachCallNode::return_value_is_used() const {


 687 // Similar to cousin class CallNode::returns_pointer
 688 // Because this is used in deoptimization, we want the type info, not the data
 689 // flow info; the interpreter will "use" things that are dead to the optimizer.
 690 bool MachCallNode::returns_pointer() const {
 691   const TypeTuple *r = tf()->range();
 692   return (r->cnt() > TypeFunc::Parms &&
 693           r->field_at(TypeFunc::Parms)->isa_ptr());
 694 }
 695 
 696 //------------------------------Registers--------------------------------------
 697 const RegMask &MachCallNode::in_RegMask(uint idx) const {
 698   // Values in the domain use the users calling convention, embodied in the
 699   // _in_rms array of RegMasks.
 700   if (idx < tf()->domain()->cnt()) {
 701     return _in_rms[idx];
 702   }
 703   if (idx == mach_constant_base_node_input()) {
 704     return MachConstantBaseNode::static_out_RegMask();
 705   }
 706   // Values outside the domain represent debug info
 707   return *Compile::current()->matcher()->idealreg2debugmask[static_cast<uint>(in(idx)->ideal_reg())];
 708 }
 709 
 710 //=============================================================================
 711 uint MachCallJavaNode::size_of() const { return sizeof(*this); }
 712 uint MachCallJavaNode::cmp( const Node &n ) const {
 713   MachCallJavaNode &call = (MachCallJavaNode&)n;
 714   return MachCallNode::cmp(call) && _method->equals(call._method) &&
 715          _override_symbolic_info == call._override_symbolic_info;
 716 }
 717 #ifndef PRODUCT
 718 void MachCallJavaNode::dump_spec(outputStream *st) const {
 719   if (_method_handle_invoke)
 720     st->print("MethodHandle ");
 721   if (_method) {
 722     _method->print_short_name(st);
 723     st->print(" ");
 724   }
 725   MachCallNode::dump_spec(st);
 726 }
 727 #endif
 728 
 729 //------------------------------Registers--------------------------------------
 730 const RegMask &MachCallJavaNode::in_RegMask(uint idx) const {
 731   // Values in the domain use the users calling convention, embodied in the
 732   // _in_rms array of RegMasks.
 733   if (idx < tf()->domain()->cnt()) {
 734     return _in_rms[idx];
 735   }
 736   if (idx == mach_constant_base_node_input()) {
 737     return MachConstantBaseNode::static_out_RegMask();
 738   }
 739   // Values outside the domain represent debug info
 740   Matcher* m = Compile::current()->matcher();
 741   // If this call is a MethodHandle invoke we have to use a different
 742   // debugmask which does not include the register we use to save the
 743   // SP over MH invokes.
 744   RegMask** debugmask = _method_handle_invoke ? m->idealreg2mhdebugmask : m->idealreg2debugmask;
 745   return *debugmask[static_cast<uint>(in(idx)->ideal_reg())];
 746 }
 747 
 748 //=============================================================================
 749 uint MachCallStaticJavaNode::size_of() const { return sizeof(*this); }
 750 uint MachCallStaticJavaNode::cmp( const Node &n ) const {
 751   MachCallStaticJavaNode &call = (MachCallStaticJavaNode&)n;
 752   return MachCallJavaNode::cmp(call) && _name == call._name;
 753 }
 754 
 755 //----------------------------uncommon_trap_request----------------------------
 756 // If this is an uncommon trap, return the request code, else zero.
 757 int MachCallStaticJavaNode::uncommon_trap_request() const {
 758   if (_name != NULL && !strcmp(_name, "uncommon_trap")) {
 759     return CallStaticJavaNode::extract_uncommon_trap_request(this);
 760   }
 761   return 0;
 762 }
 763 
 764 #ifndef PRODUCT
 765 // Helper for summarizing uncommon_trap arguments.


< prev index next >