00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 # ifdef DELTA_COMPILER
00026 
00027 
00028 
00029 
00030 
00031 class Node;                             
00032 
00033 class   TrivialNode;                    
00034 class     MergeNode;                    
00035 class     NopNode;                      
00036 class     CommentNode;                  
00037 class     FixedCodeNode;                
00038 class     LoopHeaderNode;               
00039     
00040 class   NonTrivialNode;                 
00041 
00042 class     PrologueNode;                 
00043   
00044 class     LoadNode;                     
00045 class       LoadIntNode;                
00046 class       LoadOffsetNode;             
00047 class       LoadUplevelNode;            
00048 
00049 class     StoreNode;
00050 class       AssignNode;                 
00051 class       StoreOffsetNode;            
00052 class       StoreUplevelNode;           
00053 
00054 class     AbstractReturnNode;
00055 class       ReturnNode;                 
00056 class       NLRSetupNode;               
00057 class       InlinedReturnNode;          
00058 class       NLRContinuationNode;        
00059 
00060 class     ArithNode;                    
00061 class     AbstractBranchNode;           
00062 class       TArithRRNode;               
00063 class       CallNode;                   
00064 class         SendNode;                 
00065 class         PrimNode;                 
00066 class           BlockCreateNode;        
00067 class             BlockMaterializeNode; 
00068 class           InterruptCheckNode;     
00069 class         DLLNode;                  
00070 class         ContextCreateNode;        
00071 
00072 class       AbstractArrayAtNode;
00073 class         ArrayAtNode;              
00074 class         AbstractArrayAtPutNode;
00075 class           ArrayAtPutNode;         
00076 
00077 class       InlinedPrimitiveNode;       
00078 
00079 class       BranchNode;                 
00080 class       TypeTestNode;               
00081 class       NLRTestNode;                
00082 class     ContextInitNode;              
00083 class     ContextZapNode;               
00084 
00085 class     UncommonNode;                 
00086 
00087 void initNodes();                       
00088 
00089 
00090 
00091 
00092 
00093 
00094 class PRegMapping;
00095 
00096 class BasicNode: public PrintableResourceObj {
00097  protected:     
00098   BB*           _bb;                    
00099   int16         _id;                    
00100   int16         _num;                   
00101   InlinedScope* _scope;                 
00102   int16         _bci;                   
00103   PRegMapping*  _mapping;               
00104 
00105  public:        
00106   Label         label;                  
00107   bool          dontEliminate;          
00108   bool          deleted;                
00109 
00110   int           id() const              { return this == NULL ? -1 : _id; }
00111   BB*           bb() const              { return _bb; }
00112   int           num() const             { return _num; }
00113   InlinedScope* scope() const           { return _scope; }
00114   int           bci() const             { return _bci; }
00115 
00116   void          setBB(BB* b)            { _bb = b; }
00117   void          setNum(int n)           { _num = n; }
00118   void          setScope(InlinedScope* s);
00119 
00120   static int currentID;                 
00121   static int currentCommentID;          
00122   static ScopeInfo lastScopeInfo;       
00123   static int lastBCI;
00124 
00125   BasicNode();
00126 
00127   virtual bool isPrologueNode() const           { return false; }
00128   virtual bool isAssignNode() const             { return false; }
00129   virtual bool isTArithNode() const             { return false; }
00130   virtual bool isArithNode() const              { return false; }
00131   virtual bool isNLRSetupNode() const           { return false; }
00132   virtual bool isNLRTestNode() const            { return false; }
00133   virtual bool isNLRContinuationNode() const    { return false; }
00134   virtual bool isReturnNode() const             { return false; }
00135   virtual bool isInlinedReturnNode() const      { return false; }
00136   virtual bool isLoopHeaderNode() const         { return false; }
00137   virtual bool isExitNode() const               { return false; }
00138   virtual bool isMergeNode() const              { return false; }
00139   virtual bool isBranchNode() const             { return false; }
00140   virtual bool isBlockCreateNode() const        { return false; }
00141   virtual bool isContextCreateNode() const      { return false; }
00142   virtual bool isContextInitNode() const        { return false; }
00143   virtual bool isContextZapNode() const         { return false; }
00144   virtual bool isCommentNode() const            { return false; }
00145   virtual bool isSendNode() const               { return false; }
00146   virtual bool isCallNode() const               { return false; }
00147   virtual bool isStoreNode() const              { return false; }
00148   virtual bool isDeadEndNode() const            { return false; }
00149   virtual bool isTypeTestNode() const           { return false; }
00150   virtual bool isUncommonNode() const           { return false; }
00151   virtual bool isNopNode() const                { return false; }
00152   virtual bool isCmpNode() const                { return false; }
00153   virtual bool isArraySizeLoad() const          { return false; }
00154   virtual bool isAccessingFloats() const        { return false; }
00155   virtual bool isTrivial() const                = 0;
00156 
00157   protected:
00158   virtual Node* clone(PReg* from, PReg* to) const { SubclassResponsibility(); return NULL; }
00159   void genPcDesc();
00160  public:
00161   
00162   virtual int  cost() const                     { return oopSize; }     
00163   virtual bool hasDest() const                  { return false; }
00164   virtual bool canCopyPropagate() const         { return false; }
00165         
00166         
00167           bool canCopyPropagate(Node* fromNode) const; 
00168   virtual bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false) = 0;
00169   virtual bool canCopyPropagateOop() const      { return false; }
00170         
00171         
00172   virtual bool isAssignmentLike() const         { return false; }
00173         
00174   virtual bool shouldCopyWhenSplitting() const  { return false; }
00175   virtual bool hasSrc() const                   { return false; }
00176   virtual bool hasConstantSrc() const           { return false; }
00177   virtual oop  constantSrc() const              { ShouldNotCallThis(); return 0; }
00178   virtual bool canChangeDest() const            { assert(hasDest(), "shouldn't call"); return true; }
00179 
00180   virtual bool endsBB() const                   = 0;
00181   virtual bool startsBB() const                 { return false; }
00182 
00183   int loopDepth() const                         { return _bb->loopDepth(); }
00184 
00185   virtual BB* newBB();
00186   virtual void makeUses(BB* bb) { Unused(bb); }
00187   virtual void removeUses(BB* bb) { Unused(bb); }
00188   virtual void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false) = 0;
00189   virtual bool canBeEliminated() const { return !dontEliminate; }
00190   virtual void computeEscapingBlocks(GrowableArray<BlockPReg*>* lst) { Unused(lst); }
00191   virtual void markAllocated(int* use_count, int* def_count) = 0;
00192   virtual SimpleBitVector trashedMask();
00193   virtual void gen();
00194   virtual void apply(NodeVisitor* v)            { ShouldNotCallThis(); }
00195   virtual Node* likelySuccessor() const = 0;    
00196   virtual Node* uncommonSuccessor() const = 0;  
00197   void removeUpToMerge();                       
00198   Node* copy(PReg* from, PReg* to) const;       
00199   
00200   
00201   
00202   
00203   
00204   virtual bool doesTypeTests()  const { return false; }       
00205   virtual bool hasUnknownCode() const { return false; }       
00206   virtual void collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const { ShouldNotCallThis(); }
00207           
00208   virtual void assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n) {} 
00209   virtual void assert_in_bounds(PReg* r, LoopHeaderNode* n) {}
00210 
00211   virtual void print_short();
00212   virtual void print()                  { print_short(); }
00213   virtual char* print_string(char* buf, bool printAddr = true) const = 0;
00214   void printID() const;
00215   virtual void verify() const {}
00216 
00217   
00218   
00219   
00220 
00221   PRegMapping* mapping() const;
00222   bool hasMapping() const                       { return _mapping != NULL; }
00223   void setMapping(PRegMapping* mapping);
00224 };
00225 
00226 
00227 
00228 
00229 
00230 class Node: public BasicNode {
00231  protected:
00232   Node *_prev, *_next;
00233   Node() { _prev = _next = NULL; }
00234 
00235  public:
00236   virtual bool endsBB() const;
00237   virtual Node* likelySuccessor() const;
00238   virtual Node* uncommonSuccessor() const;
00239   void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00240   virtual void verify() const;
00241 
00242   friend class NodeFactory;
00243 
00244   
00245   virtual bool hasSingleSuccessor() const               { return true; }
00246   virtual bool hasSinglePredecessor() const             { return true; }
00247   virtual int nPredecessors() const                     { return _prev ? 1 : 0; }
00248   virtual int nSuccessors() const                       { return _next ? 1 : 0; }
00249   virtual bool isPredecessor(const Node* n) const       { return _prev == n; }
00250   virtual bool isSuccessor(const Node* n) const         { return _next == n; }
00251   Node* next() const                                    { return _next; }
00252   virtual Node* next1() const                           { return NULL; }
00253   virtual Node* next(int i) const {
00254     if (i == 0) return _next; else { fatal("single next"); return NULL;} }
00255   virtual Node* firstPrev() const                       { return _prev; }
00256   virtual Node* prev(int n) const                       { if (n == 0) return _prev; else fatal("single prev"); return NULL; }
00257 
00258   virtual void setPrev(Node* p)                         { assert(_prev == NULL, "already set"); _prev = p; }
00259   virtual void movePrev(Node* from, Node* to)           { assert(_prev == from, "mismatched prev link"); _prev = to; }
00260 
00261   void setNext(Node* n)                                 { assert(_next == NULL, "already set"); _next = n; }
00262   virtual void setNext1(Node* n)                        { Unused(n); ShouldNotCallThis(); }
00263   virtual void setNext(int i, Node* n)                  { if (i == 0) setNext(n); else fatal("subclass"); }
00264   virtual void moveNext(Node* from, Node* to)           { assert(_next == from, "mismatched next link"); _next = to; }
00265 
00266  protected:
00267   virtual void removeMe();
00268   Node* endOfList() const;
00269 
00270  public:  
00271   virtual void removePrev(Node* n);
00272 
00273  public:
00274   virtual void removeNext(Node* n);                     
00275   Node* append(Node* p)                                 { setNext(p);  p->setPrev(this); return p; }
00276   Node* append1(Node* p)                                { setNext1(p); p->setPrev(this); return p; }
00277   Node* append(int i, Node* p)                          { setNext(i, p);  p->setPrev(this); return p; }
00278   Node* appendEnd(Node* p)                              { return endOfList()->append(p); }
00279 
00280   void insertNext(Node* n) {
00281     assert(hasSingleSuccessor(), ">1 successors");
00282     n->setNext(_next); n->setPrev(this);
00283     _next->movePrev(this, n); _next = n; }
00284   void insertPrev(Node* n) {
00285     assert(n->hasSinglePredecessor(), "where to insert?");
00286     n->setPrev(_prev); n->setNext(this);
00287     _prev->moveNext(this, n); _prev = n; }
00288 
00289   friend class NodeBuilder;
00290 };
00291 
00292 
00293 class TrivialNode: public Node {
00294  public:
00295   bool isTrivial() const                { return true; }
00296   int  cost() const                     { return 0; }
00297   bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false) { return false; }
00298   void markAllocated(int* use_count, int* def_count) {}
00299 
00300   
00301   
00302 
00303   friend class NodeFactory;
00304 };
00305 
00306 
00307 class NonTrivialNode: public Node {
00308  protected:
00309   PReg* _dest;                          
00310   PReg* _src;                           
00311   Use*  srcUse;                         
00312   Def*  destDef;
00313 
00314   NonTrivialNode();
00315 
00316  public:
00317   bool  isTrivial() const               { return false; }
00318   PReg* src() const;
00319   PReg* dest() const;
00320   PReg* dst() const                     { return dest(); }
00321   void  setDest(BB* bb, PReg* d);
00322   virtual bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00323   void  makeUses(BB* bb);
00324   void  removeUses(BB* bb);
00325   void  verify() const;
00326 
00327   friend class NodeFactory;
00328 };
00329 
00330 
00331 class PrologueNode : public NonTrivialNode {
00332  protected:
00333   LookupKey*  _key;
00334   const int   _nofArgs;
00335   const int   _nofTemps;
00336 
00337   PrologueNode(LookupKey* key, int nofArgs, int nofTemps) : _nofArgs(nofArgs), _nofTemps(nofTemps) {
00338     _key        = key;
00339   }
00340 
00341  public:
00342   bool isPrologueNode() const           { return true; }
00343   virtual bool canChangeDest() const    { return false; }       
00344   Node* clone(PReg* from, PReg* to) const;
00345   void makeUses(BB* bb);
00346   void removeUses(BB* bb) { ShouldNotCallThis(); }
00347   void gen();
00348   void apply(NodeVisitor* v)            { v->aPrologueNode(this); }
00349   bool canBeEliminated() const          { return false; }
00350   void markAllocated(int* use_count, int* def_count) {
00351     Unused(use_count); Unused(def_count); }
00352   char* print_string(char* buf, bool printAddr = true) const;
00353 
00354   friend class NodeFactory;
00355 };
00356 
00357 
00358 class LoadNode: public NonTrivialNode {
00359  protected:
00360   LoadNode(PReg* d)                     { _dest = d; assert(d, "dest is NULL"); }
00361 
00362  public:
00363   bool hasDest() const                  { return true; }
00364   bool canCopyPropagate() const         { return true; }
00365   bool canCopyPropagateOop() const      { return true; }
00366   void makeUses(BB* bb);
00367   void removeUses(BB* bb);
00368   void markAllocated(int* use_count, int* def_count);
00369   void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00370 
00371   friend class NodeFactory;
00372 };
00373 
00374 
00375 class LoadIntNode: public LoadNode {
00376  protected:
00377   int _value;           
00378 
00379   LoadIntNode(PReg* dst, int value) : LoadNode(dst) { _value = value; }
00380 
00381  public:
00382   Node* clone(PReg* from, PReg* to) const;
00383   int   value()                         { return _value; }
00384   void  gen();
00385   void  apply(NodeVisitor* v)           { v->aLoadIntNode(this); }
00386   char* print_string(char* buf, bool printAddr = true) const;
00387 
00388   friend class NodeFactory;
00389 };
00390 
00391 
00392 class LoadOffsetNode: public LoadNode {
00393  public:
00394   
00395   int   offset;         
00396   bool  isArraySize;    
00397 
00398  protected:
00399   LoadOffsetNode(PReg* dst, PReg* b, int offs, bool arr) : LoadNode(dst) {
00400     _src = b; offset = offs; isArraySize = arr; }
00401 
00402  public:
00403   Node* clone(PReg* from, PReg* to) const;
00404   PReg* base() const                    { return _src; }
00405   bool  hasSrc() const                  { return true; }
00406   bool  isArraySizeLoad() const         { return isArraySize; }
00407   void  makeUses(BB* bb);
00408   void  removeUses(BB* bb);
00409   void  markAllocated(int* use_count, int* def_count);
00410   void  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00411   bool  copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00412   void  gen();
00413   void  apply(NodeVisitor* v)           { v->aLoadOffsetNode(this); }
00414   void  verify() const;
00415   char* print_string(char* buf, bool printAddr = true) const;
00416 
00417   friend class NodeFactory;
00418 };
00419 
00420 
00421 class LoadUplevelNode: public LoadNode {
00422  private:
00423   Use*          _context0Use;
00424   PReg*         _context0;              
00425   int           _nofLevels;             
00426   int           _offset;                
00427   symbolOop     _name;                  
00428 
00429  protected:
00430   LoadUplevelNode(PReg* dst, PReg* context0, int nofLevels, int offset, symbolOop name);
00431 
00432  public:
00433   PReg* context0() const                { return _context0; }
00434   int   nofLevels() const               { return _nofLevels; }
00435   int   offset() const                  { return _offset; }
00436   Node* clone(PReg* from, PReg* to) const;
00437   void  makeUses(BB* bb);
00438   void  removeUses(BB* bb);
00439   void  markAllocated(int* use_count, int* def_count);
00440   bool  copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00441   void  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00442   void  gen();
00443   void  apply(NodeVisitor* v)           { v->aLoadUplevelNode(this); }
00444   void  verify() const;
00445   char* print_string(char* buf, bool printAddr = true) const;
00446 
00447   friend class NodeFactory;
00448 };
00449 
00450 
00451 class StoreNode: public NonTrivialNode {
00452  protected:
00453   StoreNode(PReg* s)                    { _src = s; assert(_src, "src is NULL"); }
00454 
00455  public:
00456   bool isStoreNode() const              { return true; }
00457   bool canCopyPropagate() const         { return true; }
00458   bool canCopyPropagateOop() const      { return true; }
00459   bool hasSrc() const                   { return true; }
00460   virtual bool needsStoreCheck() const  { return false; }
00461   virtual char* action() const          = NULL;         
00462   virtual void setStoreCheck(bool ncs)  {}
00463   void assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n);
00464   void makeUses(BB* bb);
00465   void removeUses(BB* bb);
00466   void markAllocated(int* use_count, int* def_count);
00467   void eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00468   void computeEscapingBlocks(GrowableArray<BlockPReg*>* l);
00469 
00470   friend class NodeFactory;
00471 };
00472 
00473 
00474 class StoreOffsetNode: public StoreNode {
00475   
00476   
00477  private:
00478   PReg* _base;                          
00479   Use*  _baseUse;
00480   int   _offset;                        
00481   bool  _needsStoreCheck;               
00482 
00483  protected:
00484   StoreOffsetNode(PReg* s, PReg* b, int o, bool nsc) : StoreNode(s) {
00485     _base = b; assert(b, "base is NULL"); _offset = o; _needsStoreCheck = nsc; }
00486 
00487  public:
00488   PReg* base() const                    { return _base; }
00489   int   offset() const                  { return _offset; }
00490   bool  needsStoreCheck() const         { return _needsStoreCheck; }
00491   bool  hasSrc() const                  { return true; }
00492   void  setStoreCheck(bool ncs)         { _needsStoreCheck = ncs; }
00493   char* action() const                  { return "stored into an object"; }
00494   Node* clone(PReg* from, PReg* to) const;
00495   void  makeUses(BB* bb);
00496   void  removeUses(BB* bb);
00497   void  markAllocated(int* use_count, int* def_count);
00498   bool  copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00499   void  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00500   bool  canBeEliminated() const         { return false; }
00501   void  gen();
00502   void  apply(NodeVisitor* v)           { v->aStoreOffsetNode(this); }
00503   void  verify() const;
00504   char* print_string(char* buf, bool printAddr = true) const;
00505 
00506   friend class NodeFactory;
00507 };
00508 
00509 
00510 class StoreUplevelNode: public StoreNode {
00511   
00512   
00513  private:
00514   Use*          _context0Use;
00515   PReg*         _context0;              
00516   int           _nofLevels;             
00517   int           _offset;                
00518   bool          _needsStoreCheck;       
00519   symbolOop     _name;                  
00520 
00521  protected:
00522   StoreUplevelNode(PReg* src, PReg* context0, int nofLevels, int offset, symbolOop name, bool needsStoreCheck);
00523 
00524  public:
00525   PReg* context0() const                { return _context0; }
00526   int   nofLevels() const               { return _nofLevels; }
00527   int   offset() const                  { return _offset; }
00528   bool  needsStoreCheck() const         { return _needsStoreCheck; }
00529   void  setStoreCheck(bool ncs)         { _needsStoreCheck = ncs; }
00530   char* action() const                  { return "stored into a context temporary"; }
00531   Node* clone(PReg* from, PReg* to) const;
00532   void  makeUses(BB* bb);
00533   void  removeUses(BB* bb);
00534   void  markAllocated(int* use_count, int* def_count);
00535   bool  copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00536   void  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00537   void  gen();
00538   void  apply(NodeVisitor* v)           { v->aStoreUplevelNode(this); }
00539   void  verify() const;
00540   char* print_string(char* buf, bool printAddr = true) const;
00541 
00542   friend class NodeFactory;
00543 };
00544   
00545 
00546 class AssignNode : public StoreNode {
00547   
00548  protected:
00549   AssignNode(PReg* s, PReg* d);
00550 
00551  public:
00552   int   cost() const                    { return oopSize/2; }  
00553   bool  isAccessingFloats() const;
00554   bool  isAssignNode() const            { return true; }
00555   bool  hasDest() const                 { return true; }
00556   bool  hasSrc() const                  { return true; }
00557   bool  hasConstantSrc() const          { return _src->isConstPReg(); }
00558   bool  isAssignmentLike() const        { return true; }
00559   bool  shouldCopyWhenSplitting() const { return true; }
00560   bool  canBeEliminated() const;
00561   oop   constantSrc() const;
00562   char* action() const                  { return _dest->isSAPReg() ? 
00563                                                   "passed as an argument" : "assigned to a local"; }
00564   Node* clone(PReg* from, PReg* to) const;
00565   void  makeUses(BB* bb);
00566   void  removeUses(BB* bb);
00567   void  markAllocated(int* use_count, int* def_count);
00568   void  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00569   void  gen();
00570   void  apply(NodeVisitor* v)           { v->anAssignNode(this); }
00571   char* print_string(char* buf, bool printAddr = true) const;
00572 
00573  protected:
00574   void  genOop();
00575 
00576   friend class NodeFactory;
00577 };
00578   
00579 
00580 class AbstractReturnNode: public NonTrivialNode {
00581  protected:
00582   AbstractReturnNode(int bci, PReg* src, PReg* dest)    { _bci = bci; _src = src; _dest = dest; }
00583 
00584  public:
00585   bool  canBeEliminated() const         { return false; }
00586   bool  isReturnNode() const            { return true; }
00587   bool  endsBB() const                  { return true; }
00588   bool  canCopyPropagate() const        { return true; }
00589   bool  canCopyPropagateOop() const     { return true; }
00590   bool  hasSrc() const                  { return true; }
00591   bool  isAssignmentLike() const        { return true; }
00592   bool  hasDest() const                 { return true; }
00593   void  makeUses(BB* bb);
00594   void  removeUses(BB* bb);
00595   void  computeEscapingBlocks(GrowableArray<BlockPReg*>* l);
00596   void  markAllocated(int* use_count, int* def_count) { Unused(use_count); Unused(def_count); }
00597 
00598   friend class NodeFactory;
00599 };
00600 
00601 
00602 class InlinedReturnNode: public AbstractReturnNode {
00603   
00604  protected:
00605   InlinedReturnNode(int bci, PReg* src, PReg* dest) : AbstractReturnNode(bci, src, dest) {}
00606 
00607  public:
00608   bool  isInlinedReturnNode() const     { return true; }
00609   bool  endsBB() const                  { return NonTrivialNode::endsBB(); }
00610   bool  isTrivial() const               { return true; }
00611   bool  canBeEliminated() const         { return true; }
00612   bool  shouldCopyWhenSplitting() const { return true; }
00613   int   cost() const                    { return 0; }
00614   Node* clone(PReg* from, PReg* to) const;
00615   void  gen();
00616   void  apply(NodeVisitor* v)           { v->anInlinedReturnNode(this); }
00617   void  verify() const;
00618   char* print_string(char* buf, bool printAddr = true) const;
00619 
00620   friend class NodeFactory;
00621 };
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 class NLRSetupNode: public AbstractReturnNode {
00631   Use*  resultUse;
00632   Use*  contextUse;                     
00633  protected:
00634   NLRSetupNode(PReg* result, int bci);
00635 
00636  public:
00637   bool  isExitNode() const              { return true; }
00638   bool  isNLRSetupNode() const          { return true; }
00639   
00640   bool  canCopyPropagate() const        { return false; }
00641   bool  canCopyPropagateOop() const     { return false; }
00642   bool  hasSrc() const                  { return false; }
00643   bool  isAssignmentLike() const        { return false; }
00644   bool  hasDest() const                 { return false; }
00645   bool  canChangeDest() const           { return false; }       
00646   Node* clone(PReg* from, PReg* to) const;
00647   void  makeUses(BB* bb);
00648   void  removeUses(BB* bb);
00649   void  gen();
00650   void  apply(NodeVisitor* v)           { v->aNLRSetupNode(this); }
00651   void  verify() const;
00652   char* print_string(char* buf, bool printAddr = true) const;
00653 
00654   friend class NodeFactory;
00655 };
00656 
00657 
00658 class NLRContinuationNode: public AbstractReturnNode {
00659  protected:
00660   NLRContinuationNode(int bci, PReg* src, PReg* dest) : AbstractReturnNode(bci, src, dest) { }
00661 
00662  public:
00663   bool  isExitNode() const              { return true; }
00664   bool  isNLRContinuationNode() const   { return true; }
00665   
00666   bool  canCopyPropagate() const        { return false; }
00667   bool  canCopyPropagateOop() const     { return false; }
00668   bool  hasSrc() const                  { return false; }
00669   bool  isAssignmentLike() const        { return false; }
00670   bool  hasDest() const                 { return false; }
00671   bool  canChangeDest() const           { return false; }       
00672   Node* clone(PReg* from, PReg* to) const;
00673   void  makeUses(BB* bb);
00674   void  removeUses(BB* bb);
00675   void  gen();
00676   void  apply(NodeVisitor* v)           { v->aNLRContinuationNode(this); }
00677   void  verify() const;
00678   char* print_string(char* buf, bool printAddr = true) const;
00679 
00680   friend class NodeFactory;
00681 };
00682 
00683 
00684 
00685 class ReturnNode: public AbstractReturnNode {
00686  private:
00687   Use*  resultUse;
00688 
00689  protected:
00690   ReturnNode(PReg* res, int bci);
00691 
00692  public:
00693   Node* clone(PReg* from, PReg* to) const;
00694   bool  isExitNode() const              { return true; }
00695   bool  hasSrc() const                  { return false; }
00696   bool  isAssignmentLike() const        { return false; }
00697   bool  hasDest() const                 { return false; }
00698   void  makeUses(BB* bb);
00699   void  removeUses(BB* bb);
00700   void  markAllocated(int* use_count, int* def_count);
00701   void  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00702   void  gen();
00703   void  apply(NodeVisitor* v)           { v->aReturnNode(this); }
00704   void  verify() const;
00705   char* print_string(char* buf, bool printAddr = true) const;
00706 
00707   friend class NodeFactory;
00708 };
00709 
00710 
00711 
00712 
00713 
00714 class AbstractMergeNode: public TrivialNode {
00715  private:
00716   enum { N = 3 };
00717   
00718  protected:
00719   GrowableArray<Node*>* _prevs;
00720 
00721  public:
00722   AbstractMergeNode()                   { _prevs = new GrowableArray<Node*>(N); }
00723   AbstractMergeNode(Node* prev1, Node* prev2) {
00724     _prevs = new GrowableArray<Node*>(N);
00725     _prevs->append(prev1); prev1->setNext(this);
00726     _prevs->append(prev2); prev2->setNext(this);
00727   }
00728 
00729   bool hasSinglePredecessor() const     { return _prevs->length() <= 1; }
00730   int nPredecessors() const             { return _prevs->length(); }
00731   Node* firstPrev() const               { return _prevs->isEmpty() ? NULL : _prevs->at(0); }
00732 
00733   void setPrev(Node* p) {
00734     assert(p, "should be something");
00735     assert(!_prevs->contains(p), "shouldn't already be there");
00736     _prevs->append(p);
00737   }
00738 
00739   Node* prev(int n) const               { return _prevs->at(n); }
00740 
00741  protected:
00742   void removeMe();
00743   virtual void removePrev(Node* n) {
00744     
00745     _prevs->remove(n);
00746   }
00747 
00748  public:
00749   void movePrev(Node* from, Node* to);
00750   bool isPredecessor(const Node* n) const;
00751 };
00752 
00753 
00754 class MergeNode : public AbstractMergeNode {
00755  protected:
00756   MergeNode(int bci);
00757   MergeNode(Node* prev1, Node* prev2);
00758   
00759  public:
00760   bool  isLoopStart;                    
00761   bool  isLoopEnd;                      
00762   bool  didStartBB;                     
00763   int   cost() const                    { return 0; }
00764   bool  isTrivial() const               { return _prevs->length() <= 1; }
00765   bool  startsBB() const                { return _prevs->length() > 1 || isLoopStart; }
00766   bool  isMergeNode() const             { return true; }
00767   BB*   newBB();
00768   Node* clone(PReg* from, PReg* to) const;
00769   void  gen();
00770   void  apply(NodeVisitor* v)           { v->aMergeNode(this); }
00771   void  verify() const;
00772   char* print_string(char* buf, bool printAddr = true) const;
00773 
00774   friend class NodeFactory;
00775 };
00776     
00777 
00778 class ArithNode : public NonTrivialNode {       
00779   
00780  protected:
00781   ArithOpCode   _op;
00782   ConstPReg*    _constResult;   
00783 
00784   ArithNode(ArithOpCode op, PReg* src, PReg* dst) {
00785     _op = op; _src = src; _dest = dst; _constResult = NULL;
00786   }
00787 
00788  public:
00789   bool          canCopyPropagate() const        { return true; }
00790   bool          canCopyPropagateOop() const     { return true; }
00791   bool          hasSrc() const                  { return true; }
00792   bool          hasDest() const                 { return true; }
00793   bool          isAssignmentLike() const        { return _constResult != NULL; }
00794   bool          isArithNode() const             { return true; }
00795   bool          isCmpNode() const               { return _op == tCmpArithOp; }
00796   void          makeUses(BB* bb);
00797   void          removeUses(BB* bb);
00798   void          markAllocated(int* use_count, int* def_count);
00799   void          eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00800   bool          copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00801   ArithOpCode   op() const                      { return _op; }
00802   virtual bool  operIsConst() const = 0;
00803   virtual int   operConst() const = 0;
00804   virtual bool  doCopyPropagate(BB* bb, Use* u, PReg* d, bool repl);
00805   char*         opName() const;
00806 
00807   friend class NodeFactory;
00808 };
00809 
00810 
00811 class ArithRRNode : public ArithNode {  
00812  protected:
00813   PReg* _oper;
00814   Use*  _operUse;
00815 
00816   ArithRRNode(ArithOpCode o, PReg* s, PReg* o2, PReg* d);
00817 
00818  public:
00819   PReg* operand() const                         { return _oper; }
00820   Node* clone(PReg* from, PReg* to) const;
00821   bool  operIsConst() const;
00822   int   operConst() const;
00823   bool  doCopyPropagate(BB* bb, Use* u, PReg* d, bool replace);
00824   void  makeUses(BB* bb);
00825   void  removeUses(BB* bb);
00826   void  markAllocated(int* use_count, int* def_count);
00827   void  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
00828   void  gen();
00829   void  apply(NodeVisitor* v)                   { v->anArithRRNode(this); }
00830   void  verify() const;
00831   char* print_string(char* buf, bool printAddr = true) const;
00832 
00833   friend class NodeFactory;
00834 };
00835 
00836 
00837 class FloatArithRRNode : public ArithRRNode {  
00838   FloatArithRRNode(ArithOpCode o, PReg* s, PReg* o2, PReg* d) : ArithRRNode(o, s, o2, d) { }
00839  public:
00840   bool  isAccessingFloats() const               { return true; }
00841   bool  copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00842   void  gen();
00843   void  apply(NodeVisitor* v)                   { v->aFloatArithRRNode(this); }
00844   void  verify() const;
00845   char* print_string(char* buf, bool printAddr = true) const;
00846 
00847   friend class NodeFactory;
00848 };
00849 
00850 
00851 class FloatUnaryArithNode : public ArithNode {  
00852   
00853   
00854   FloatUnaryArithNode(ArithOpCode op, PReg* src, PReg* dst) : ArithNode(op, src, dst) {}
00855  public:
00856   bool  isAccessingFloats() const               { return true; }
00857   bool  isCmpNode() const                       { return false; }
00858   bool  copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00859   bool  operIsConst() const                     { return false; }
00860   int   operConst() const                       { ShouldNotCallThis(); return 0; }
00861   void  gen();
00862   void  apply(NodeVisitor* v)                   { v->aFloatUnaryArithNode(this); }
00863   void  verify() const;
00864   char* print_string(char* buf, bool printAddr = true) const;
00865   friend class NodeFactory;
00866 };
00867 
00868 
00869 class ArithRCNode : public ArithNode {  
00870   
00871   
00872  protected:
00873   int   _oper;
00874 
00875   ArithRCNode(ArithOpCode o, PReg* s, int o2, PReg* d)
00876     : ArithNode(o, s, d) { _oper = o2; }
00877 
00878  public:
00879   int   operand() const                         { return _oper; }
00880   Node* clone(PReg* from, PReg* to) const;
00881   void  gen();
00882   void  apply(NodeVisitor* v)                   { v->anArithRCNode(this); }
00883   bool  operIsConst() const                     { return true; }
00884   int   operConst() const                       { return _oper; }
00885   char* print_string(char* buf, bool printAddr = true) const;
00886 
00887   friend class NodeFactory;
00888 };
00889 
00890 
00891 class AbstractBranchNode : public NonTrivialNode {
00892   
00893  public:
00894   virtual bool  canFail() const = NULL;         
00895   virtual Node* failureBranch() const           { return next1(); }
00896   bool          endsBB() const                  { return true; }
00897  protected:
00898   AbstractBranchNode()                          { _nxt = new GrowableArray<Node*>(EstimatedSuccessors); }
00899   void          removeFailureIfPossible();
00900   void          verify(bool verifySuccessors) const;
00901 
00902   
00903  private:
00904   enum { EstimatedSuccessors = 2 };             
00905  protected:
00906   GrowableArray<Node*>* _nxt;                   
00907  public:
00908 
00909   Node* next1() const                           { return _nxt->length() ? _nxt->at(0) : NULL; }
00910   bool hasSingleSuccessor() const               { return next1() == NULL; }
00911   int nSuccessors() const                       { return _nxt->length() + (_next ? 1 : 0); }
00912   Node* next() const                            { return _next; }
00913   Node* next(int i) const                       { return i == 0 ? _next : _nxt->at(i-1); }
00914 
00915   void removeMe();
00916   void removeNext(Node* n);
00917 
00918   void setNext1(Node* n) {
00919     assert(_nxt->length() == 0, "already set");
00920     _nxt->append(n);
00921   }
00922 
00923   void setNext(Node* n)                         { NonTrivialNode::setNext(n); }
00924   void setNext(int i, Node* n);
00925   void moveNext(Node* from, Node* to);
00926   bool isSuccessor(const Node* n) const;
00927 };
00928 
00929 class TArithRRNode : public AbstractBranchNode {  
00930   
00931   
00932  protected:
00933   ArithOpCode   _op;
00934   PReg*         _oper;
00935   Use*          _operUse;
00936   bool          _arg1IsInt;                     
00937   bool          _arg2IsInt;                     
00938   ConstPReg*    _constResult;                   
00939 
00940   TArithRRNode(ArithOpCode o, PReg* s, PReg* o2, PReg* d, bool a1, bool a2);
00941 
00942  public:
00943   ArithOpCode   op() const                      { return _op; }
00944   PReg*         operand() const                 { return _oper; }
00945   bool          arg1IsInt() const               { return _arg1IsInt; }
00946   bool          arg2IsInt() const               { return _arg2IsInt; }
00947   bool          canFail() const                 { return !(_arg1IsInt && _arg2IsInt); }
00948   bool          isTArithNode() const            { return true; }
00949   bool          isAssignmentLike() const        { return _constResult != NULL; }
00950   bool          canCopyPropagate() const        { return true; }
00951   bool          canCopyPropagateOop() const     { return true; }
00952   bool          hasSrc() const                  { return true; }
00953   bool          hasDest() const                 { return true; }
00954 
00955   bool          doesTypeTests()  const          { return true; }
00956   bool          hasUnknownCode() const;
00957   void          collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const;
00958   void          assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n);
00959 
00960   void          makeUses(BB* bb);
00961   void          removeUses(BB* bb);
00962   void          markAllocated(int* use_count, int* def_count);
00963   Node*         clone(PReg* from, PReg* to) const;
00964   bool          copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00965   Node*         likelySuccessor() const;
00966   Node*         uncommonSuccessor() const;
00967   void          gen();
00968   void          apply(NodeVisitor* v)           { v->aTArithRRNode(this); }
00969   void          verify() const;
00970   char*         print_string(char* buf, bool printAddr = true) const;
00971 
00972  protected:
00973   bool          doCopyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
00974 
00975   friend class NodeFactory;
00976 };
00977 
00978 
00979 class CallNode : public AbstractBranchNode {
00980   
00981   
00982  protected:
00983   CallNode(MergeNode* n, GrowableArray<PReg*>* args, GrowableArray<PReg*>* exprs);
00984   
00985  public:
00986   GrowableArray<PReg*>* exprStack;      
00987   GrowableArray<Use*>*  argUses;        
00988   GrowableArray<PReg*>* uplevelUsed;    
00989   GrowableArray<PReg*>* uplevelDefd;    
00990   GrowableArray<Use*>*  uplevelUses;    
00991   GrowableArray<Def*>*  uplevelDefs;    
00992   GrowableArray<PReg*>* args;           
00993   int                   nblocks;        
00994         
00995   bool hasDest() const                  { return true; }
00996   bool isCallNode() const               { return true; }
00997   bool canChangeDest() const            { return false; }
00998   bool canBeEliminated() const          { return false; }
00999   virtual bool canInvokeDelta() const = NULL;   
01000   MergeNode* nlrTestPoint() const;
01001   Node* likelySuccessor() const;
01002   Node* uncommonSuccessor() const;
01003   bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
01004   void computeEscapingBlocks(GrowableArray<BlockPReg*>* ll);
01005   void makeUses(BB* bb);
01006   void removeUses(BB* bb);
01007   void markAllocated(int* use_count, int* def_count);
01008   SimpleBitVector trashedMask();
01009   void nlrCode();                       
01010   void verify() const;
01011 
01012   friend class NodeFactory;
01013 };
01014 
01015 
01016 class SendNode : public CallNode {
01017  protected:
01018   LookupKey* _key;        
01019   bool       _superSend;  
01020   SendInfo*  _info;       
01021 
01022   SendNode(
01023     LookupKey* key,
01024     MergeNode* nlrTestPoint,
01025     GrowableArray<PReg*>* args,
01026     GrowableArray<PReg*>* exprStk,
01027     bool superSend,
01028     SendInfo* info
01029   );
01030 
01031  public:
01032   bool  isSendNode() const              { return true; }
01033   bool  isSuperSend() const             { return _superSend; }
01034   bool  isCounting() const;
01035   bool  isUninlinable() const;
01036   bool  staticReceiver() const;
01037   bool  canInvokeDelta() const          { return true; }
01038   bool  canFail() const                 { return false; }
01039   int   cost() const                    { return oopSize * 5; }   
01040   PReg* recv() const;
01041   Node* clone(PReg* from, PReg* to) const;
01042   void  computeEscapingBlocks(GrowableArray<BlockPReg*>* ll);
01043   void  gen();
01044   void  apply(NodeVisitor* v)           { v->aSendNode(this); }
01045   char* print_string(char* buf, bool printAddr = true) const;
01046 
01047   friend class NodeFactory;
01048 };
01049 
01050 
01051 class PrimNode: public CallNode {
01052  protected:
01053   primitive_desc*       _pdesc;
01054 
01055   PrimNode(primitive_desc* pdesc, MergeNode* nlrTestPoint, GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack);
01056 
01057  public:
01058   bool                  canBeEliminated() const;
01059   bool                  canInvokeDelta() const;
01060   bool                  canFail() const;
01061   primitive_desc*       pdesc() const           { return _pdesc; }
01062   Node*                 clone(PReg* from, PReg* to) const;
01063   void                  computeEscapingBlocks(GrowableArray<BlockPReg*>* ll);
01064   void                  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01065   void                  gen();
01066   void                  apply(NodeVisitor* v)   { v->aPrimNode(this); }
01067   char*                 print_string(char* buf, bool printAddr = true) const;
01068 
01069   friend class NodeFactory;
01070 };
01071 
01072 
01073 class DLLNode: public CallNode {
01074  protected:
01075   symbolOop     _dll_name;
01076   symbolOop     _function_name;
01077   dll_func      _function;
01078   bool          _async;
01079 
01080   DLLNode(symbolOop dll_name, symbolOop function_name, dll_func function, bool async,
01081           MergeNode* nlrTestPoint, GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack);
01082 
01083  public:
01084   bool          canInvokeDelta() const;
01085   bool          canFail() const                 { return true; }
01086   int           nofArguments() const            { return args == NULL ? 0 : args->length(); }
01087   symbolOop     dll_name() const                { return _dll_name; }
01088   symbolOop     function_name() const           { return _function_name; }
01089   dll_func      function() const                { return _function; }
01090   bool          async() const                   { return _async; }
01091   void          computeEscapingBlocks(GrowableArray<BlockPReg*>* ll);
01092   Node*         clone(PReg* from, PReg* to) const;
01093   void          gen();
01094   void          apply(NodeVisitor* v)           { v->aDLLNode(this); }
01095   char*         print_string(char* buf, bool printAddr = true) const;
01096 
01097   friend class NodeFactory;
01098 };
01099 
01100 
01101 class InterruptCheckNode : public PrimNode {
01102  protected:
01103   static primitive_desc* _intrCheck;
01104 
01105   InterruptCheckNode(GrowableArray<PReg*>* exprs)
01106     : PrimNode(_intrCheck, NULL, NULL, exprs) {}
01107 
01108  public:
01109   Node* clone(PReg* from, PReg* to) const;
01110   void  gen();
01111   void  apply(NodeVisitor* v)           { Unimplemented(); }
01112   char* print_string(char* buf, bool printAddr = true) const;
01113 
01114   friend void node_init();
01115   friend class NodeFactory;
01116 };
01117 
01118 
01119 
01120 
01121 class LoopHeaderNode : public TrivialNode {
01122  protected:
01123   
01124   bool  _integerLoop;                                   
01125   PReg* _loopVar;                                       
01126   PReg* _lowerBound;                                    
01127   PReg* _upperBound;                                    
01128   LoadOffsetNode* _upperLoad;                           
01129   GrowableArray<AbstractArrayAtNode*>* _arrayAccesses;  
01130   
01131   GrowableArray<HoistedTypeTest*>* _tests;              
01132   bool _activated;                                      
01133   LoopHeaderNode* _enclosingLoop;                       
01134   GrowableArray<LoopHeaderNode*>* _nestedLoops;         
01135   int  _nofCalls;                                       
01136   GrowableArray<LoopRegCandidate*>* _registerCandidates;
01137 
01138   LoopHeaderNode();
01139 
01140  public:
01141   bool  isLoopHeaderNode() const                                { return true; }
01142   bool  isActivated() const                                     { return _activated; }
01143   bool  isInnerLoop() const                                     { return _nestedLoops == NULL; }
01144   bool  isIntegerLoop() const                                   { return _integerLoop; }
01145   PReg* loopVar() const                                         { return _loopVar; }
01146   PReg* lowerBound() const                                      { return _lowerBound; }
01147   PReg* upperBound() const                                      { return _upperBound; }
01148   LoadOffsetNode*                       upperLoad() const       { return _upperLoad; }
01149   GrowableArray<AbstractArrayAtNode*>*  arrayAccesses() const   { return _arrayAccesses; }
01150   GrowableArray<HoistedTypeTest*>*      tests() const           { return _tests; }
01151   Node* clone(PReg* from, PReg* to) const                       { ShouldNotCallThis(); return NULL; }
01152   int   nofCallsInLoop() const                                  { return _nofCalls; }
01153   void  set_nofCallsInLoop(int n)                               { _nofCalls = n; }
01154   void  activate(PReg* loopVar, PReg* lowerBound, PReg* upperBound, LoadOffsetNode* upperLoad);
01155   void  activate();                                             
01156   void  addArray(AbstractArrayAtNode* n);
01157   LoopHeaderNode* enclosingLoop() const                         { return _enclosingLoop; }
01158   void  set_enclosingLoop(LoopHeaderNode* l);
01159   GrowableArray<LoopHeaderNode*>* nestedLoops() const           { return _nestedLoops; }
01160   void  addNestedLoop(LoopHeaderNode* l);
01161   GrowableArray<LoopRegCandidate*>* registerCandidates() const  { return _registerCandidates; }
01162   void  addRegisterCandidate(LoopRegCandidate* c);
01163   void  gen();
01164   void  apply(NodeVisitor* v)                                   { v->aLoopHeaderNode(this); }
01165   char* print_string(char* buf, bool printAddr = true) const;
01166 
01167   friend class NodeFactory;
01168   friend class CompiledLoop;
01169  protected:
01170    void generateTypeTests(Label& cont, Label& failure);
01171    void generateIntegerLoopTests(Label& cont, Label& failure);
01172    void generateArrayLoopTests(Label& cont, Label& failure);
01173    void generateIntegerLoopTest(PReg* p, Label& cont, Label& failure);
01174    void handleConstantTypeTest(ConstPReg* r, GrowableArray<klassOop>* klasses);
01175 };
01176 
01177 
01178 class BlockCreateNode : public PrimNode {
01179   
01180   
01181   
01182  protected:
01183   PReg*                         _context;       
01184   Use*                          _contextUse;    
01185 
01186   void materialize();                           
01187   void copyIntoContexts(Register val, Register t1, Register t2);    
01188 
01189   BlockCreateNode(BlockPReg* b, GrowableArray<PReg*>* expr_stack);
01190 
01191  public:
01192   bool  isBlockCreateNode() const       { return true; }
01193   
01194   bool  endsBB() const                  { return !isMemoized() || NonTrivialNode::endsBB(); }
01195   BlockPReg* block() const              { assert(_dest->isBlockPReg(), "must be BlockPReg"); return (BlockPReg*)_dest; }
01196   bool  isMemoized() const              { return block()->isMemoized(); }
01197   bool  hasConstantSrc() const          { return false; }
01198   bool  hasSrc() const                  { return false; }
01199   int   cost() const                    { return 2*oopSize; }    
01200   Node* clone(PReg* from, PReg* to) const;
01201   bool  canBeEliminated() const         { return !dontEliminate; }
01202   void  makeUses(BB* bb);
01203   void  removeUses(BB* bb);
01204   void  markAllocated(int* use_count, int* def_count);
01205   void  gen();
01206   void  apply(NodeVisitor* v)           { v->aBlockCreateNode(this); }
01207   void  verify() const;
01208   char* print_string(char* buf, bool printAddr = true) const;
01209 
01210   friend void node_init();
01211 
01212   friend class NodeFactory;
01213 };
01214 
01215 
01216 class BlockMaterializeNode : public BlockCreateNode {
01217   
01218   
01219  protected:
01220   BlockMaterializeNode(BlockPReg* b, GrowableArray<PReg*>* expr_stack)
01221     : BlockCreateNode(b, expr_stack) { _src = _dest; }
01222 
01223  public:
01224   bool  endsBB() const                  { return true; }
01225   bool  hasSrc() const                  { return true; }
01226   int   cost() const                    { return 5*oopSize; } 
01227   Node* clone(PReg* from, PReg* to) const;
01228   void  makeUses(BB* bb);
01229   void  removeUses(BB* bb);
01230   void  markAllocated(int* use_count, int* def_count);
01231   void  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01232   void  gen();
01233   void  apply(NodeVisitor* v)           { v->aBlockMaterializeNode(this); }
01234   char* print_string(char* buf, bool printAddr = true) const;
01235 
01236   friend class NodeFactory;
01237 };
01238 
01239 
01240 class ContextCreateNode: public PrimNode {
01241   
01242  protected:
01243   int                           _nofTemps;                      
01244   int                           _contextSize;                   
01245   int                           _contextNo;                     
01246   GrowableArray<PReg*>*         _parentContexts;                
01247   GrowableArray<Use*>*          _parentContextUses;             
01248 
01249   ContextCreateNode(PReg* parent, PReg* context, int nofTemps, GrowableArray<PReg*>* expr_stack);
01250   ContextCreateNode(PReg* b, const ContextCreateNode* n, GrowableArray<PReg*>* expr_stack); 
01251 
01252  public:
01253   bool          hasSrc() const                                  { return _src != NULL; }
01254   bool          canChangeDest() const                           { return false; }
01255   bool          canBeEliminated() const                         { return false; }
01256   bool          isContextCreateNode() const                     { return true; }
01257   bool          canFail() const                                 { return false; }
01258   PReg*         context() const                                 { return _dest; }
01259   int           nofTemps() const                                { return _nofTemps; }
01260   int           sizeOfContext() const                           { return _contextSize; }
01261   void          set_sizeOfContext(int s )                       { _contextSize = s; }
01262   int           contextNo() const                               { return _contextNo; }
01263   void          set_contextNo(int s )                           { _contextNo = s; }
01264 
01265   Node*         clone(PReg* from, PReg* to) const;
01266   void          makeUses(BB* bb);
01267   void          removeUses(BB* bb);
01268   void          eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01269   void          markAllocated(int* use_count, int* def_count);
01270   void          gen();
01271   void          apply(NodeVisitor* v)                           { v->aContextCreateNode(this); }
01272   void          verify() const;
01273   char*         print_string(char* buf, bool printAddr = true) const;
01274 
01275   friend void   node_init();
01276 
01277   friend class NodeFactory;
01278 };
01279 
01280 
01281 class ContextInitNode: public NonTrivialNode {
01282   
01283  protected:
01284   GrowableArray<Expr*>*         _initializers;          
01285   GrowableArray<Def*>*          _contentDefs;
01286   GrowableArray<Use*>*          _initializerUses;
01287   GrowableArray<BlockMaterializeNode*>* _materializedBlocks;    
01288                                                                 
01289 
01290   ContextInitNode(ContextCreateNode* creator);
01291   ContextInitNode(PReg* b, const ContextInitNode* node);        
01292 
01293  public:
01294   bool          hasSrc() const                          { return _src != NULL; }
01295   bool          hasDest() const                         { return false; }
01296   bool          isContextInitNode() const               { return true; }
01297   bool          canCopyPropagate() const                { return true; }
01298   bool          canBeEliminated() const                 { return false; }
01299   bool          wasEliminated() const                   { return _src == NULL; }
01300   GrowableArray<Expr*>* contents() const                { return scope()->contextTemporaries(); }
01301   int           nofTemps() const                        { return _initializers->length(); }
01302   Expr*         contextTemp(int i) const                { return contents()->at(i); }
01303   Expr*         initialValue(int i) const               { return _initializers->at(i); }
01304   void          addBlockMaterializer(BlockMaterializeNode* n);
01305   ContextCreateNode* creator() const;
01306   void          notifyNoContext();
01307   bool          hasNoContext() const                    { return _src == NULL; }
01308 
01309   void          initialize(int no, Expr* expr);         
01310   int           positionOfContextTemp(int i) const;     
01311   Node*         clone(PReg* from, PReg* to) const;
01312   void          makeUses(BB* bb);
01313   void          removeUses(BB* bb);
01314   void          eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01315   bool          copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
01316   void          markAllocated(int* use_count, int* def_count);
01317   void          computeEscapingBlocks(GrowableArray<BlockPReg*>* l);
01318   void          gen();
01319   void          apply(NodeVisitor* v)                   { v->aContextInitNode(this); }
01320   void          verify() const;
01321   char*         print_string(char* buf, bool printAddr = true) const;
01322 
01323   friend void   node_init();
01324 
01325   friend class NodeFactory;
01326 };
01327 
01328 
01329 class ContextZapNode: public NonTrivialNode {
01330 
01331  private:
01332   ContextZapNode(PReg* context)                 { _src = context; assert(_src, "src is NULL"); }
01333   
01334  public:
01335   bool  isActive() const                        { return scope()->needsContextZapping(); }
01336   bool  isContextZapNode() const                { return true; }
01337   bool  hasSrc() const                          { return true; }
01338   bool  shouldCopyWhenSplitting() const         { return true; }
01339   PReg* context() const                         { return _src; }
01340 
01341   Node* clone(PReg* from, PReg* to) const;
01342   void  makeUses(BB* bb);
01343   void  removeUses(BB* bb);
01344   void  markAllocated(int* use_count, int* def_count);
01345   void  gen();
01346   void  apply(NodeVisitor* v)                   { v->aContextZapNode(this); }
01347   void  verify() const;
01348   char* print_string(char* buf, bool printAddr = true) const;
01349 
01350   friend class NodeFactory;
01351 };
01352 
01353 
01354 class NLRTestNode: public AbstractBranchNode {
01355   
01356   
01357   
01358  protected:
01359   NLRTestNode(int bci);
01360 
01361  public:
01362   bool  isNLRTestNode() const                   { return true; }
01363   bool  canChangeDest() const                   { return false; }
01364   bool  canBeEliminated() const                 { return false; }
01365   bool  canFail() const                         { return false; }
01366   void  fixup();                                
01367 
01368   Node* clone(PReg* from, PReg* to) const;
01369   void  makeUses(BB* bb);
01370   void  removeUses(BB* bb);
01371   
01372   void  markAllocated(int* use_count, int* def_count) {};
01373   Node* likelySuccessor() const;
01374   Node* uncommonSuccessor() const;
01375   void  gen();
01376   void  apply(NodeVisitor* v)                   { v->aNLRTestNode(this); }
01377   void  verify() const;
01378   char* print_string(char* buf, bool printAddr = true) const;
01379 
01380   friend class NodeFactory;
01381 };
01382 
01383 
01384 class BranchNode : public AbstractBranchNode {
01385   
01386   
01387   
01388  protected:
01389   BranchOpCode  _op;                            
01390   bool          _taken_is_uncommon;             
01391 
01392   BranchNode(BranchOpCode op, bool taken_is_uncommon) {
01393     _op = op;
01394     _taken_is_uncommon = taken_is_uncommon;
01395   }
01396 
01397  public:
01398   BranchOpCode  op() const                      { return _op; }
01399   bool          isBranchNode() const            { return true; }
01400   bool          canFail() const                 { return false; }
01401   void          eliminateBranch(int op1, int op2, int res);
01402   void          eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01403   void          markAllocated(int* use_count, int* def_count) { Unused(use_count); Unused(def_count); }
01404   Node*         clone(PReg* from, PReg* to) const;
01405   Node*         likelySuccessor() const;
01406   Node*         uncommonSuccessor() const;
01407   void          gen();
01408   void          apply(NodeVisitor* v)           { v->aBranchNode(this); }
01409   char*         print_string(char* buf, bool printAddr = true) const;
01410   void          verify()                        { AbstractBranchNode::verify(false); }  
01411 
01412   friend class NodeFactory;
01413 };
01414 
01415 
01416 class TypeTestNode : public AbstractBranchNode {
01417   
01418   
01419   
01420  protected:
01421   GrowableArray<klassOop>* _classes;    
01422   bool _hasUnknown;                     
01423                                         
01424 
01425   bool needsKlassLoad() const;          
01426   TypeTestNode(PReg* r, GrowableArray<klassOop>* classes, bool hasUnknown);
01427 
01428  public:
01429   GrowableArray<klassOop>* classes() const      { return _classes; }
01430   bool  hasUnknown() const                      { return _hasUnknown; }
01431   bool  canFail() const                         { return _hasUnknown; }
01432   Node* failureBranch() const                   { return next(); }
01433   void  setUnknown(bool u)                      { _hasUnknown = u; }
01434   bool  isTypeTestNode() const                  { return true; }
01435   bool  hasSrc() const                          { return true; }
01436   bool  canCopyPropagate() const                { return true; }
01437   bool  canCopyPropagateOop() const             { return true; }
01438   int   cost() const                            { return 2 * oopSize * (_classes->length() + needsKlassLoad() ? 1 : 0); }
01439   Node* smiCase() const;                        
01440 
01441   bool  doesTypeTests()  const                  { return true; }
01442   bool  hasUnknownCode() const;                 
01443   void  collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const;
01444   void  assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n);
01445 
01446   Node* clone(PReg* from, PReg* to) const;
01447   bool  copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
01448   void  makeUses(BB* bb);
01449   void  removeUses(BB* bb);
01450   void  markAllocated(int* use_count, int* def_count);
01451   void  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01452   void  eliminate(BB* bb, PReg* r, ConstPReg* c, klassOop m);
01453   void  eliminateUnnecessary(klassOop m);
01454   Node* likelySuccessor() const;
01455   Node* uncommonSuccessor() const;
01456   void  gen();
01457   void  apply(NodeVisitor* v)                   { v->aTypeTestNode(this); }
01458   void  verify() const;
01459   char* print_string(char* buf, bool printAddr = true) const;
01460 
01461   friend class NodeFactory;
01462 };
01463 
01464 
01465 class AbstractArrayAtNode : public AbstractBranchNode {
01466   
01467   
01468  protected:
01469                                 
01470   PReg* _arg;                   
01471   Use*  _argUse;
01472   bool  _intArg;                
01473   PReg* _error;                 
01474   Def*  _errorDef;
01475   bool  _needBoundsCheck;       
01476   int   _dataOffset;            
01477   int   _sizeOffset;            
01478 
01479    AbstractArrayAtNode(PReg* r, PReg* idx, bool ia, PReg* res, PReg* err, int dataOffset, int sizeOffset) {
01480      _src = r; _arg = idx; _intArg = ia; _dest = res; _error = err;
01481      _dataOffset = dataOffset; _sizeOffset = sizeOffset;
01482      dontEliminate = true; _needBoundsCheck = true;
01483    }
01484 
01485  public:
01486   bool  hasSrc() const                  { return true; }
01487   bool  hasDest() const                 { return _dest != NULL; }
01488   bool  canFail() const = NULL;
01489   int   cost() const                    { return 20 + (_intArg ? 0 : 12); } 
01490   bool  canCopyPropagate() const        { return true; }
01491   int   sizeOffset() const              { return _sizeOffset; }
01492   bool  copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
01493 
01494   bool  doesTypeTests() const           { return true; }
01495   bool  needsBoundsCheck() const        { return _needBoundsCheck; }
01496   bool  hasUnknownCode() const;
01497   void  collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const;
01498   void  assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n);
01499   void  assert_in_bounds(PReg* r, LoopHeaderNode* n);
01500 
01501   void  makeUses(BB* bb);
01502   void  removeUses(BB* bb);
01503   void  markAllocated(int* use_count, int* def_count);
01504   void  eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01505   Node* likelySuccessor() const;
01506   Node* uncommonSuccessor() const;
01507 
01508   friend class NodeFactory;
01509 };
01510 
01511 
01512 class ArrayAtNode : public AbstractArrayAtNode {
01513  public:
01514   enum AccessType {
01515     byte_at,                            
01516     double_byte_at,                     
01517     character_at,                       
01518     object_at                           
01519   };
01520 
01521  protected:
01522   AccessType    _access_type;
01523 
01524   ArrayAtNode(
01525     AccessType  access_type,            
01526     PReg*       array,                  
01527     PReg*       index,                  
01528     bool        smiIndex,               
01529     PReg*       result,                 
01530     PReg*       error,                  
01531     int         data_offset,            
01532     int         length_offset           
01533   );
01534 
01535  public:
01536   AccessType    access_type() const     { return _access_type; }
01537   PReg*         array() const           { return _src; }
01538   PReg*         index() const           { return _arg; }
01539   PReg*         error() const           { return _error; }
01540   bool          index_is_smi() const    { return _intArg; }
01541   bool          index_needs_bounds_check() const { return _needBoundsCheck; }
01542   bool          canFail() const         { return !index_is_smi() || index_needs_bounds_check(); }
01543   int           data_word_offset() const{ return _dataOffset; }
01544   int           size_word_offset() const{ return _sizeOffset; }
01545   Node*         clone(PReg* from, PReg* to) const;
01546   char*         print_string(char* buf, bool printAddr = true) const;
01547   void          gen();
01548   void          apply(NodeVisitor* v)   { v->anArrayAtNode(this); }
01549 
01550   friend class  NodeFactory;
01551 };
01552 
01553 
01554 class AbstractArrayAtPutNode : public AbstractArrayAtNode {
01555   
01556   
01557  protected:
01558   PReg* elem;
01559   Use* elemUse;
01560 
01561    AbstractArrayAtPutNode(PReg* arr, PReg* idx, bool ia, PReg* el, PReg* res, PReg* err, int doff, int soff)
01562     : AbstractArrayAtNode(arr, idx, ia, res, err, doff, soff) { elem = el; }
01563 
01564  public:
01565   bool copyPropagate(BB* bb, Use* u, PReg* d, bool replace = false);
01566   bool canCopyPropagateOop() const      { return true; }
01567   void makeUses(BB* bb);
01568   void removeUses(BB* bb);
01569   void markAllocated(int* use_count, int* def_count);
01570 
01571   friend class NodeFactory;
01572 };
01573  
01574 
01575 class ArrayAtPutNode : public AbstractArrayAtPutNode {
01576  public:
01577   enum AccessType {
01578     byte_at_put,                        
01579     double_byte_at_put,                 
01580     object_at_put                       
01581   };
01582   static bool stores_smi_elements(AccessType t) { return t != object_at_put; }
01583 
01584  protected:
01585   AccessType    _access_type;
01586   bool          _needs_store_check;
01587   bool          _smi_element;
01588   bool          _needs_element_range_check;
01589 
01590   ArrayAtPutNode(
01591     AccessType  access_type,            
01592     PReg*       array,                  
01593     PReg*       index,                  
01594     bool        smi_index,              
01595     PReg*       element,                
01596     bool        smi_element,            
01597     PReg*       result,                 
01598     PReg*       error,                  
01599     int         data_offset,            
01600     int         length_offset,          
01601     bool        needs_store_check       
01602   );
01603 
01604  public:
01605   AccessType    access_type() const     { return _access_type; }
01606   PReg*         array() const           { return _src; }
01607   PReg*         index() const           { return _arg; }
01608   PReg*         element() const         { return elem; }
01609   PReg*         error() const           { return _error; }
01610   bool          index_is_smi() const    { return _intArg; }
01611   bool          element_is_smi() const  { return _smi_element; }
01612   bool          index_needs_bounds_check() const { return _needBoundsCheck; }
01613   bool          element_needs_range_check() const { return _needs_element_range_check; }
01614   bool          canFail() const         { return !index_is_smi() || index_needs_bounds_check() ||
01615                                                   (access_type() != object_at_put && (!element_is_smi() || element_needs_range_check())); }
01616   bool          needs_store_check() const { return _needs_store_check; }
01617   int           data_word_offset() const{ return _dataOffset; }
01618   int           size_word_offset() const{ return _sizeOffset; }
01619   Node*         clone(PReg* from, PReg* to) const;
01620 
01621   void          collectTypeTests(GrowableArray<PReg*>& regs, GrowableArray<GrowableArray<klassOop>*>& klasses) const;
01622   void          assert_preg_type(PReg* r, GrowableArray<klassOop>* klasses, LoopHeaderNode* n);
01623 
01624   void          computeEscapingBlocks(GrowableArray<BlockPReg*>* l);
01625   char*         print_string(char* buf, bool printAddr = true) const;
01626   void          gen();
01627   void          apply(NodeVisitor* v)   { v->anArrayAtPutNode(this); }
01628 
01629   friend class NodeFactory;
01630 };
01631 
01632 
01633 class InlinedPrimitiveNode : public AbstractBranchNode {
01634  public:
01635   enum Operation {
01636     obj_klass,                          
01637     obj_hash,                           
01638     proxy_byte_at,                      
01639     proxy_byte_at_put,                  
01640   };
01641 
01642  private:
01643   Operation     _op;
01644   
01645   PReg*         _arg1;                  
01646   PReg*         _arg2;                  
01647   PReg*         _error;                 
01648   Use*          _arg1_use;
01649   Use*          _arg2_use;
01650   Def*          _error_def;
01651   bool          _arg1_is_smi;           
01652   bool          _arg2_is_smi;           
01653 
01654   InlinedPrimitiveNode(
01655     Operation op,
01656     PReg* result,
01657     PReg* error,
01658     PReg* recv,
01659     PReg* arg1, bool arg1_is_smi,
01660     PReg* arg2, bool arg2_is_smi
01661   );
01662 
01663  public:
01664   Operation     op() const              { return _op; }
01665   PReg*         arg1() const            { return _arg1; }
01666   PReg*         arg2() const            { return _arg2; }
01667   PReg*         error() const           { return _error; }
01668   bool          arg1_is_smi() const     { return _arg1_is_smi; }
01669   bool          arg2_is_smi() const     { return _arg2_is_smi; }
01670   bool          hasSrc() const          { return _src != NULL; }
01671   bool          hasDest() const         { return _dest != NULL; }
01672   bool          canFail() const;
01673   void          makeUses(BB* bb);
01674   void          removeUses(BB* bb);
01675   void          markAllocated(int* use_count, int* def_count);
01676   bool          canBeEliminated() const;
01677   void          eliminate(BB* bb, PReg* r, bool removing = false, bool cp = false);
01678   bool          canCopyPropagate() const        { return false; }
01679   bool          canCopyPropagateOop() const     { return false; }
01680   bool          copyPropagate(BB* bb, Use* u, PReg* d, bool replace);
01681   Node*         likelySuccessor() const;
01682   Node*         uncommonSuccessor() const;
01683   void          gen();
01684   void          apply(NodeVisitor* v)           { v->anInlinedPrimitiveNode(this); }
01685   void          verify() const;
01686   char*         print_string(char* buf, bool printAddr = true) const;
01687   
01688   friend class NodeFactory;
01689 };
01690 
01691 
01692 class UncommonNode : public NonTrivialNode {
01693   GrowableArray<PReg*>* exprStack;
01694  
01695  protected:
01696   UncommonNode(GrowableArray<PReg*>* e, int bci);
01697 
01698  public:
01699   bool  isUncommonNode() const          { return true; }
01700   int   cost() const                    { return 4; } 
01701   bool  isExitNode() const              { return true; }
01702   bool  isEndsBB() const                { return true; }
01703   Node* clone(PReg* from, PReg* to) const;
01704   void  markAllocated(int* use_count, int* def_count) { Unused(use_count); Unused(def_count); }
01705   void  gen();
01706   void  apply(NodeVisitor* v)           { v->anUncommonNode(this); }
01707   void  verify() const;
01708   char* print_string(char* buf, bool printAddr = true) const;
01709 
01710   friend class NodeFactory;
01711 };
01712 
01713 
01714 class FixedCodeNode : public TrivialNode {
01715  public:
01716   enum FixedCodeKind {
01717     dead_end,                           
01718     inc_counter                         
01719   };
01720  protected:
01721   const FixedCodeKind _kind;
01722   FixedCodeNode(FixedCodeKind k) : _kind(k) {}
01723 
01724  public:
01725   bool  isExitNode() const              { return _kind == dead_end; }
01726   bool  isDeadEndNode() const           { return _kind == dead_end; }
01727   FixedCodeKind kind() const            { return _kind; }
01728   Node* clone(PReg* from, PReg* to) const;
01729   void  gen();
01730   void  apply(NodeVisitor* v)           { v->aFixedCodeNode(this); }
01731   char* print_string(char* buf, bool printAddr = true) const;
01732 
01733   friend class NodeFactory;
01734 };
01735 
01736 
01737 class NopNode : public TrivialNode {
01738  protected:
01739   NopNode() {}
01740 
01741  public:
01742   bool  isNopNode() const               { return true; }
01743   Node* clone(PReg* from, PReg* to) const;
01744   void  apply(NodeVisitor* v)           { v->aNopNode(this); }
01745   char* print_string(char* buf, bool printAddr = true) const;
01746 
01747   friend class NodeFactory;
01748 };
01749 
01750 
01751 class CommentNode : public TrivialNode {
01752  protected:
01753   CommentNode(char* s);
01754   
01755  public:
01756   char* comment;
01757   bool  isCommentNode() const           { return true; }
01758   Node* clone(PReg* from, PReg* to) const;
01759   void  apply(NodeVisitor* v)           { v->aCommentNode(this); }
01760   char* print_string(char* buf, bool printAddr = true) const;
01761 
01762   friend class NodeFactory;
01763 };
01764 
01765 
01766 
01767 
01768 class NodeFactory : AllStatic {
01769  public:
01770   static int cumulCost;                                 
01771 
01772   static void                   registerNode(Node* n)   { cumulCost += n->cost(); }
01773 
01774   static PrologueNode*          new_PrologueNode        (LookupKey* key, int nofArgs, int nofTemps);
01775 
01776   static LoadOffsetNode*        new_LoadOffsetNode      (PReg* dst, PReg* base, int offs, bool isArray);
01777   static LoadUplevelNode*       new_LoadUplevelNode     (PReg* dst, PReg* context0, int nofLevels, int offset, symbolOop name);
01778   static LoadIntNode*           new_LoadIntNode         (PReg* dst, int value);
01779   
01780   static StoreOffsetNode*       new_StoreOffsetNode     (PReg* src, PReg* base, int offs, bool needStoreCheck);
01781   static StoreUplevelNode*      new_StoreUplevelNode    (PReg* src, PReg* context0, int nofLevels, int offset, symbolOop name, bool needStoreCheck);
01782   static AssignNode*            new_AssignNode          (PReg* src, PReg* dst);
01783 
01784   static ReturnNode*            new_ReturnNode          (PReg* res, int bci);
01785   static InlinedReturnNode*     new_InlinedReturnNode   (int bci, PReg* src, PReg* dst);
01786   static NLRSetupNode*          new_NLRSetupNode        (PReg* result, int bci);
01787   static NLRContinuationNode*   new_NLRContinuationNode (int bci);
01788   static NLRTestNode*           new_NLRTestNode         (int bci);
01789 
01790   static ArithRRNode*           new_ArithRRNode         (PReg* dst, PReg* src, ArithOpCode op, PReg* o2);
01791   static ArithRCNode*           new_ArithRCNode         (PReg* dst, PReg* src, ArithOpCode op, int   o2);
01792   static TArithRRNode*          new_TArithRRNode        (PReg* dst, PReg* src, ArithOpCode op, PReg* o2, bool a1, bool a2);
01793   static FloatArithRRNode*      new_FloatArithRRNode    (PReg* dst, PReg* src, ArithOpCode op, PReg* o2);
01794   static FloatUnaryArithNode*   new_FloatUnaryArithNode (PReg* dst, PReg* src, ArithOpCode op);
01795 
01796   static MergeNode*             new_MergeNode           (Node* prev1, Node* prev2);
01797   static MergeNode*             new_MergeNode           (int bci);
01798 
01799   static SendNode*              new_SendNode            (LookupKey* key, MergeNode* nlrTestPoint,
01800                                                          GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack, 
01801                                                          bool superSend, SendInfo* info);
01802   static PrimNode*              new_PrimNode            (primitive_desc* pdesc, MergeNode* nlrTestPoint,
01803                                                          GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack);
01804   static DLLNode*               new_DLLNode             (symbolOop dll_name, symbolOop function_name, dll_func function, bool async,
01805                                                          MergeNode* nlrTestPoint, GrowableArray<PReg*>* args, GrowableArray<PReg*>* expr_stack);
01806 
01807   static InterruptCheckNode*    new_InterruptCheckNode  (GrowableArray<PReg*>* expr_stack);
01808   static LoopHeaderNode*        new_LoopHeaderNode      ();
01809   
01810   static BlockCreateNode*       new_BlockCreateNode     (BlockPReg* b, GrowableArray<PReg*>* expr_stack);
01811   static BlockMaterializeNode*  new_BlockMaterializeNode(BlockPReg* b, GrowableArray<PReg*>* expr_stack);
01812 
01813   static ContextCreateNode*     new_ContextCreateNode   (PReg* parent, PReg* context, int nofTemps, GrowableArray<PReg*>* expr_stack);
01814   static ContextCreateNode*     new_ContextCreateNode   (PReg* b, const ContextCreateNode* n, GrowableArray<PReg*>* expr_stack);
01815   static ContextInitNode*       new_ContextInitNode     (ContextCreateNode* creator);
01816   static ContextInitNode*       new_ContextInitNode     (PReg* b, const ContextInitNode* n);
01817   static ContextZapNode*        new_ContextZapNode      (PReg* context);
01818 
01819   static BranchNode*            new_BranchNode          (BranchOpCode op, bool taken_is_uncommon = false);
01820 
01821   static TypeTestNode*          new_TypeTestNode        (PReg* recv, GrowableArray<klassOop>* classes, bool hasUnknown);
01822 
01823   static ArrayAtNode*           new_ArrayAtNode         (ArrayAtNode::AccessType access_type, PReg* array, PReg* index, bool smiIndex,
01824                                                          PReg* result, PReg* error, int data_offset, int length_offset);
01825 
01826   static ArrayAtPutNode*        new_ArrayAtPutNode      (ArrayAtPutNode::AccessType access_type, PReg* array, PReg* index, bool smi_index,
01827                                                          PReg* element, bool smi_element, PReg* result, PReg* error, int data_offset, int length_offset,
01828                                                          bool needs_store_check);
01829   
01830   static InlinedPrimitiveNode*  new_InlinedPrimitiveNode(InlinedPrimitiveNode::Operation op, PReg* result, PReg* error = NULL,
01831                                                          PReg* recv = NULL,
01832                                                          PReg* arg1 = NULL, bool arg1_is_smi = false,
01833                                                          PReg* arg2 = NULL, bool arg2_is_smi = false);
01834 
01835   static UncommonNode*          new_UncommonNode        (GrowableArray<PReg*>* exprStack, int bci);
01836   static FixedCodeNode*         new_FixedCodeNode       (FixedCodeNode::FixedCodeKind k);
01837   static NopNode*               new_NopNode             ();
01838   static CommentNode*           new_CommentNode         (char* comment);
01839 };
01840 
01841 #ifdef DEBUG
01842 void printNodes(Node* n);   
01843 #endif
01844 
01845 # endif