expr.cpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996, LongView Technologies L.L.C. $Revision: 1.47 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 
00025 # include "incls/_precompiled.incl"
00026 
00027 # ifdef DELTA_COMPILER
00028 # include "incls/_expr.cpp.incl"
00029 
00030 const int UnknownExpr::UnlikelyBit        = 1;
00031 const int MergeExpr::SplittableBit        = 2;
00032 const int MergeExpr::UnknownSetBit        = 4;
00033 const int MergeExpr::ContainingUnknownBit = 8;
00034 
00035 const int MaxMergeExprSize = 5; // max. # exprs in a merge expression
00036 
00037 Expr::Expr(PReg* p, Node* n) { 
00038   assert(p, "must have PReg");
00039   _preg = p; _node = n; next = NULL; flags = 0; 
00040   assert(p->scope()->isInlinedScope(), "should be InlinedScope");
00041   assert(n != NodeBuilder::EndOfCode, "should be a real node");
00042 }
00043 
00044 
00045 MergeExpr::MergeExpr(Expr* e1, Expr* e2, PReg* p, Node* nod) : Expr(p, nod) {
00046   initialize();
00047   if (!p) _preg = e1->preg();
00048   mergeInto(e1, nod); 
00049   mergeInto(e2, nod);
00050 #ifdef ASSERT
00051   verify();
00052 #endif
00053 }
00054 
00055 MergeExpr::MergeExpr(PReg* p, Node* nod) : Expr(p, nod) { initialize(); }
00056 
00057 void MergeExpr::initialize() {
00058   exprs = new GrowableArray<Expr*>(MaxMergeExprSize); // NB: won't grow beyond MaxMergeExprSize
00059   setSplittable(_node != NULL);
00060 }
00061 
00062 NoResultExpr::NoResultExpr(Node* n) : Expr(new NoPReg(n ? n->scope() : theCompiler->currentScope()), n) {}
00063 
00064 ContextExpr::ContextExpr(PReg* r) : Expr(r, NULL) {}
00065 
00066 KlassExpr::KlassExpr(klassOop k, PReg* p, Node* n) : Expr(p, n) {
00067   _klass = k;
00068   assert(k, "must have klass");
00069 }
00070   
00071 BlockExpr::BlockExpr(BlockPReg* p, Node* n) 
00072   : KlassExpr(blockClosureKlass::blockKlassFor(p->closure()->nofArgs()), p, n) {
00073   assert(n, "must have a node");
00074   _blockScope = p->scope();
00075 }
00076 
00077 Expr* Expr::asReceiver() const { 
00078   // the receiver is the Expr* for a newly created InlinedScope; return the Expr that
00079   // should be used as the new scope's receiver
00080   assert(hasKlass(), "must have klass");
00081   return (Expr*)this; 
00082 }
00083 
00084 Expr* MergeExpr::asReceiver() const {
00085   return new KlassExpr(klass(), _preg, _node);
00086 }
00087 
00088 // equals: do two expression denote the same type information?
00089 
00090 bool UnknownExpr::equals(Expr* other) const {
00091   return other->isUnknownExpr();
00092 }
00093 
00094 bool NoResultExpr::equals(Expr* other) const {
00095   return other->isNoResultExpr();
00096 }
00097 
00098 bool KlassExpr::equals(Expr* other) const {
00099   return (other->isKlassExpr() || other->isConstantExpr()) &&
00100     other->klass() == klass();
00101 }
00102 
00103 bool BlockExpr::equals(Expr* other) const {
00104   return other->isBlockExpr() && other->klass() == klass();
00105 }
00106 
00107 bool ConstantExpr::equals(Expr* other) const {
00108   return other->isConstantExpr() && other->constant() == constant() ||
00109     other->isKlassExpr() && other->klass() == klass();
00110 }
00111 
00112 bool MergeExpr::equals(Expr* other) const {
00113   Unused(other);
00114   return false; // for now -- fix this later
00115 }  
00116 
00117 // mergeWith: return receiver merged with arg; functional (does not modify receiver or arg expr)
00118 Expr* UnknownExpr::mergeWith(Expr* other, Node* n) {
00119   if (other->isNoResultExpr()) return this;
00120   if (other->isUnknownExpr()) {
00121     if (n && node() && other->node()) {
00122       // preserve splitting info
00123       MergeExpr* e = new MergeExpr(this, other, preg(), n);
00124       assert(e->isSplittable(), "wasted effort");
00125       return e;
00126     } else {
00127       _node = NULL;     // prevent future splitting
00128       return this;
00129     }
00130   } else {
00131     PReg* r = _preg == other->preg() ? _preg : NULL;
00132     return new MergeExpr(this, other, r, n);
00133   }
00134 }
00135 
00136 Expr* NoResultExpr::mergeWith(Expr* other, Node* n)  {
00137   Unused(n);
00138   return other; 
00139 }
00140 
00141 Expr* KlassExpr::mergeWith(Expr* other, Node* n)  {
00142   if (other->isNoResultExpr()) return this;
00143   if ((other->isKlassExpr() || other->isConstantExpr())
00144       && other->klass() == klass()) {
00145     // generalize klass + constant in same clone family --> klass
00146     _node = NULL;       // prevent future splitting
00147     return this;
00148   } else {
00149     PReg* r = _preg == other->preg() ? _preg : NULL;
00150     return new MergeExpr(this, other, r, n);
00151   }
00152 }
00153 
00154 Expr* BlockExpr::mergeWith(Expr* other, Node* n) {
00155   if (other->isNoResultExpr()) return this;
00156   if (equals(other)) {
00157     if (n && node() && other->node()) {
00158       // preserve splitting info
00159       MergeExpr* e = new MergeExpr(this, other, preg(), n);
00160       assert(e->isSplittable(), "wasted effort");
00161       return e;
00162     } else {
00163       _node = NULL;     // prevent future splitting
00164       return this;
00165     }
00166   } else {
00167     PReg* r = _preg == other->preg() ? _preg : NULL;
00168     return new MergeExpr(this, other, r, n);
00169   }
00170 }
00171 
00172 Expr* ConstantExpr::mergeWith(Expr* other, Node* n)  {
00173   // NB: be careful not to turn true & false into klasses
00174   if (other->isNoResultExpr()) return this;
00175   if (other->isConstantExpr()
00176       && other->constant() == constant()) {
00177     if (n && node() && other->node()) {
00178       // preserve splitting info
00179       MergeExpr* e = new MergeExpr(this, other, preg(), n);
00180       assert(e->isSplittable(), "wasted effort");
00181       return e;
00182     } else {
00183       _node = NULL;     // prevent future splitting
00184       return this;
00185     }
00186   } else if (other->isKlassExpr()) {
00187     return other->mergeWith(this, n);
00188   } else {
00189     PReg* r = _preg == other->preg() ? _preg : NULL;
00190     return new MergeExpr(this, other, r, n);
00191   }
00192 }
00193 
00194 Expr* MergeExpr::mergeWith(Expr* other, Node* n) {
00195   assert(_preg == other->preg() || other->isNoResultExpr(), "mismatched PRegs");
00196   return new MergeExpr(this, other, _preg, n);
00197 }
00198 
00199 // mergeInto: merge other expr into receiver; modifies receiver
00200 void MergeExpr::mergeInto(Expr* other, Node* n) {
00201   if (other->isNoResultExpr()) return;
00202   setUnknownSet(false);
00203   if (n == NULL) setSplittable(false);
00204   _node = n;
00205   if (other->isMergeExpr()) {
00206     MergeExpr* o = other->asMergeExpr();
00207     if (o->isSplittable() && !isSplittable()) {
00208       int i = 0;
00209     }
00210     for (int i = 0; i < o->exprs->length(); i++) {
00211       // must be careful when adding splittable exprs (e->next != NULL)
00212       // to avoid creating loops in the ->next chain
00213       Expr* e = o->exprs->at(i);
00214       Expr* nexte;
00215       for ( ; e; e = nexte) {
00216         nexte = e->next;
00217         e->next = NULL;
00218         add(e);
00219       }
00220     }
00221   } else {
00222     add(other);
00223   }
00224 #ifdef ASSERT
00225   int len = exprs->length();
00226   for (int i = 0; i < len; i++) {
00227     Expr* e = exprs->at(i);
00228     for (int j = i + 1; j < len; j++) {
00229       Expr* e2 = exprs->at(j);
00230       assert(! e->equals(e2), "duplicate expr");
00231       assert(! (e->hasKlass() && e2->hasKlass() && e->klass() == e2->klass()),
00232              "duplicate klasses");
00233     }
00234   }
00235 #endif
00236   assert(!isSplittable() || _node, "splittable mergeExpr must have a node");
00237 }
00238 
00239 // add a new expression to the receiver
00240 void MergeExpr::add(Expr* e) {
00241   assert(e->next == NULL, "shouldn't be set");
00242   setUnknownSet(false);
00243   if (exprs->isFull()) {
00244     setSplittable(false);
00245     return;
00246   }
00247   if (!e->node()) setSplittable(false);
00248   for (int i = 0; i < exprs->length(); i++) {
00249     Expr* e1 = exprs->at(i);
00250     if (e->hasKlass() && e1->hasKlass() && e->klass() == e1->klass() ||
00251         e->equals(e1)) {
00252       // an equivalent expression is already in our list
00253       // if unsplittable we don't need to do anything except
00254       // if e is a klass and the expr we already have is a constant
00255       // (otherwise: might later make unknown unlikely and rely on
00256       // constant value)
00257       if (!isSplittable() && !e1->isConstantExpr()) return;
00258       
00259       // even though the klass is already in our list, we care about
00260       // the new entry because we might have to copy the nodes between
00261       // it and the split send
00262       // Therefore, we keep lists of equivalent Exprs (linked via the
00263       // "next" field).
00264       Node* n = e->node();
00265       if (n) {
00266         for (Expr* e2 = exprs->at(i); e2; e2 = e2->next) {
00267           if (n == e2->node()) {
00268             // node already in list; this can happen if we're merging an expression
00269             // with itself (e.g. we inlined 2 cases, both return the same argument)
00270             // can't treat as splittable anymore
00271             setSplittable(false);
00272             break;
00273           }
00274         }
00275      }
00276 
00277       // generalize different constants to klasses
00278       if (e->isConstantExpr() && e1->isConstantExpr() &&
00279           e->constant() == e1->constant()) {
00280         // leave them as constants
00281       } else {
00282         if (e->isConstantExpr()) {
00283           e = e->convertToKlass(e->preg(), e->node());
00284         }
00285         if (e1->isConstantExpr()) {
00286           // convertToKlass e1 and replace it in receiver
00287           Expr* ee = e1->convertToKlass(e1->preg(), e1->node());
00288           ee->next = e1->next;
00289           exprs->at_put(i, ee);
00290         }
00291       }
00292       if (!isSplittable()) return;
00293       // append e at end of e1's next chain
00294       for (e1 = exprs->at(i); e1->next; e1 = e1->next) ;
00295       e1->next = e;
00296       return;
00297     }
00298   }
00299   if (exprs->length() == MaxMergeExprSize) {
00300     // our capacity overflows, so make sure we've got at least one Unknown
00301     // type in our set
00302     if (findUnknown() == NULL) exprs->append(new UnknownExpr(e->preg(), NULL));
00303   } else {
00304     exprs->append(e);
00305   }
00306 }
00307 
00308 int MergeExpr::nklasses() const {
00309   int n = 0;
00310   for (int i = 0; i < exprs->length(); i++) {
00311     n += exprs->at(i)->nklasses();
00312   }
00313   return n;
00314 }
00315 
00316 
00317 // copyWithout: return receiver w/o the argument expression
00318 
00319 Expr* KlassExpr::copyWithout(Expr* e) const {
00320   assert(e->klass() == klass(), "don't have this klass");
00321   return new NoResultExpr(node());
00322 }
00323 
00324 
00325 Expr* ConstantExpr::copyWithout(Expr* e) const {
00326   assert(e->constant() == constant(), "don't have this constant");
00327   return new NoResultExpr(node());
00328 }
00329 
00330 Expr* MergeExpr::copyWithout(Expr* e) const {
00331   MergeExpr* res = (MergeExpr*)shallowCopy(preg(), node());
00332   res->exprs->remove(e);
00333   return res;
00334 }
00335 
00336 
00337 
00338 bool MergeExpr::really_hasKlass(InlinedScope* s) const {
00339   // Check if receiver really has only one klass.  Specifically, if we're
00340   // at the place that made the receiver's unknown part unlikely, the
00341   // receiver should *not* be considered a KlassExpr because the unknown
00342   // part hasn't been tested yet.
00343   return hasKlass() && !(s == unlikelyScope && s->bci() <= unlikelyBCI);
00344 }
00345 
00346 bool MergeExpr::hasKlass() const {
00347   // treat a merge expr like a single klass if it contains only one klass and
00348   // possibly an unlikely unknown
00349   if (exprs->length() > 2) return false;
00350   Expr* e1 = exprs->at(0);
00351   bool haveKlass1 = e1->hasKlass();
00352   if (exprs->length() == 1) return haveKlass1;  // only one expr
00353   UnknownExpr* u1 = e1->findUnknown();
00354   if (u1 && !u1->isUnlikely()) return false;  // 1st = likely unknown
00355   Expr* e2 = exprs->at(1);
00356   bool haveKlass2 = e2->hasKlass();
00357   UnknownExpr* u2 = e2->findUnknown();
00358   if (u2 && !u2->isUnlikely()) return false;  // 2nd = likely unknown
00359   if (haveKlass1 && haveKlass2) return false;   // 2 klasses
00360   // success!  one expr may have klass, one is unlikely unknown
00361   return haveKlass1 || haveKlass2;
00362 }
00363 
00364 KlassExpr* MergeExpr::asKlassExpr() const {
00365   assert(hasKlass(), "don't have a klass");
00366   Expr* e = exprs->at(0);
00367   return e->hasKlass() ? e->asKlassExpr() : exprs->at(1)->asKlassExpr();
00368 }
00369 
00370 klassOop MergeExpr::klass() const {
00371   assert(hasKlass(), "don't have a klass");
00372   Expr* e = exprs->at(0);
00373   return e->hasKlass() ? e->klass() : exprs->at(1)->klass();
00374 }
00375 
00376 bool MergeExpr::hasConstant() const {
00377   // see hasKlass()...also, must be careful about different constants with
00378   // same klass (i.e. expr->next is set)
00379   return false;
00380 }
00381 
00382 oop MergeExpr::constant() const {
00383   ShouldNotCallThis();
00384   return 0;
00385 }
00386 
00387 Expr* ConstantExpr::convertToKlass(PReg* p, Node* n) const {
00388   return new KlassExpr(_c->klass(), p, n);
00389 }
00390 
00391 KlassExpr* ConstantExpr::asKlassExpr() const {
00392   return new KlassExpr(_c->klass(), _preg, _node);
00393 }
00394 
00395 Expr* MergeExpr::convertToKlass(PReg* p, Node* n) const {
00396   MergeExpr* e = new MergeExpr(p, n);
00397   for (int i = 0; i < exprs->length(); i++) {
00398     Expr* expr = exprs->at(i)->convertToKlass(p, n);
00399     e->add(expr);
00400   }
00401   // result is non-splittable because nodes aren't correct and expr->next
00402   // is ignored for the components of the receiver
00403   e->setSplittable(false);
00404   return e;
00405 }
00406 
00407 bool MergeExpr::containsUnknown() {
00408   if (isUnknownSet()) {
00409     assert ((findUnknown() == NULL) != isContainingUnknown(), "isContainingUnknown wrong");
00410     return isContainingUnknown();
00411   }
00412   setUnknownSet(true);
00413   for (int i = 0; i < exprs->length(); i++) {
00414     if (exprs->at(i)->isUnknownExpr()) {
00415       setContainingUnknown(true);
00416       return true;
00417     }
00418   }
00419   setContainingUnknown(false);
00420   return false;
00421 }
00422 
00423 UnknownExpr* MergeExpr::findUnknown() const {
00424   for (int i = 0; i < exprs->length(); i++) {
00425     if (exprs->at(i)->isUnknownExpr()) return (UnknownExpr*)exprs->at(i);
00426   }
00427   return NULL;
00428 }
00429 
00430 Expr* MergeExpr::findKlass(klassOop klass) const {
00431   for (int i = 0; i < exprs->length(); i++) {
00432     Expr* e = exprs->at(i);
00433     if (e->hasKlass() && e->klass() == klass) return e;
00434   }
00435   return NULL;
00436 }
00437 
00438 Expr* UnknownExpr::makeUnknownUnlikely(InlinedScope* s)    {
00439   Unused(s);
00440   assert(DeferUncommonBranches, "shouldn't make unlikely");
00441   // called on an UnknownExpr itself, this is a no-op; works only
00442   // with merge exprs
00443   return this;
00444 }
00445 
00446 Expr* MergeExpr::makeUnknownUnlikely(InlinedScope* s) {
00447   assert(DeferUncommonBranches, "shouldn't make unlikely");
00448   unlikelyScope = s; unlikelyBCI = s->bci();
00449   for (int i = 0; i < exprs->length(); i++) {
00450     Expr* e;
00451     if ((e = exprs->at(i))->isUnknownExpr()) {
00452       if (!((UnknownExpr*)e)->isUnlikely()) {
00453         // must make a copy to avoid side-effecting e.g. incoming arg
00454         UnknownExpr* u = (UnknownExpr*)e;
00455         UnknownExpr* new_u = new UnknownExpr(u->preg(), u->node(), true);
00456         exprs->at_put(i, new_u);
00457         for (u = (UnknownExpr*)u->next; u;
00458                                         u = (UnknownExpr*)u->next, new_u = (UnknownExpr*)new_u->next){
00459           new_u->next = new UnknownExpr(u->preg(), u->node(), true);
00460         }
00461       }
00462       return this;
00463     }
00464   }
00465   ShouldNotReachHere(); // contains no unknown expression
00466   return NULL;
00467 }
00468 
00469 Expr* ConstantExpr::findKlass(klassOop m) const { return klass() == m ? (Expr*)this : NULL; }
00470 
00471 // needsStoreCheck: when storing the expr into the heap, do we need a GC store check?
00472 bool KlassExpr::needsStoreCheck() const {
00473   return _klass != smiKlassObj;
00474 }
00475   
00476 bool ConstantExpr::needsStoreCheck() const {
00477   // don't need a check if either
00478   // - it's a smi, or
00479   // - it's an old object (old objects never become young again)
00480   return ! (_c->is_smi() || _c->is_old());
00481 }
00482   
00483 Expr* UnknownExpr::shallowCopy(PReg* p, Node* n) const {
00484   return new UnknownExpr(p, n, isUnlikely());
00485 }
00486 
00487 Expr* NoResultExpr::shallowCopy(PReg* p, Node* n) const {
00488   Unused(p); Unused(n);
00489   return new NoResultExpr();
00490 }
00491 
00492 Expr* KlassExpr::shallowCopy(PReg* p, Node* n) const {
00493   return new KlassExpr(_klass, p, n);
00494 }
00495 
00496 Expr* BlockExpr::shallowCopy(PReg* p, Node* n) const {
00497   if (p->isBlockPReg()) {
00498     return new BlockExpr((BlockPReg*)p, n);
00499   } else {
00500     // remove block info (might be a performance bug -- should keep
00501     // around info so can inline (but: would have to check for non-LIFO
00502     // cases, e.g. when non-clean block is returned from a method)
00503     return new UnknownExpr(p, n);
00504   }
00505 }
00506 
00507 Expr* ConstantExpr::shallowCopy(PReg* p, Node* n) const {
00508   return new ConstantExpr(_c, p, n);
00509 }
00510 
00511 Expr* MergeExpr::shallowCopy(PReg* p, Node* n) const {
00512   MergeExpr* e = new MergeExpr(p, n);
00513   e->exprs = exprs->copy();
00514   e->setSplittable(isSplittable());
00515   return e;
00516 }
00517 
00518 InlinedScope* Expr::scope() const { 
00519   assert(_preg->scope()->isInlinedScope(), "oops");
00520   return (InlinedScope*)_preg->scope(); 
00521 }
00522 
00523 NameNode* Expr::nameNode(bool mustBeLegal) const {
00524   return preg()->nameNode(mustBeLegal); }
00525   
00526 NameNode* ConstantExpr::nameNode(bool mustBeLegal) const {
00527   Unused(mustBeLegal);
00528 //c    return newValueName(constant()); }
00529   return 0;
00530 }
00531 
00532 void Expr::print_helper(char* type) {
00533   lprintf(" (Node %#lx)", node());
00534   if (next) lprintf(" (next %#lx)", next);
00535   lprintf("    ((%s*)%#x)\n", type, this);
00536 }
00537   
00538 void UnknownExpr::print() {
00539   lprintf("UnknownExpr %s", isUnlikely() ? "unlikely" : "");
00540   Expr::print_helper("UnknownExpr");
00541 }
00542 
00543 void NoResultExpr::print() { lprintf("NoResultExpr "); Expr::print_helper("NoResultExpr"); }
00544 void ContextExpr::print()  { lprintf("ContextExpr %s", preg()->safeName()); Expr::print_helper("ContextExpr"); }
00545 
00546 void ConstantExpr::print() {
00547   lprintf("ConstantExpr %s", constant()->print_value_string()); Expr::print_helper("ConstantExpr");
00548 }
00549 
00550 void KlassExpr::print() {
00551   lprintf("KlassExpr %s", klass()->print_value_string()); Expr::print_helper("KlassExpr"); 
00552 }
00553 
00554 void BlockExpr::print() {
00555   lprintf("BlockExpr %s", preg()->name()); Expr::print_helper("BlockExpr"); 
00556 }
00557 
00558 void MergeExpr::print() {
00559   lprintf("MergeExpr %s(\n", isSplittable() ? "splittable " : "");
00560   for (int i = 0; i < exprs->length(); i++) {
00561     lprintf("\t%#lx%s ", exprs->at(i), exprs->at(i)->next ? "*" : "");
00562     exprs->at(i)->print();
00563   }
00564   lprintf(")");
00565   Expr::print_helper("MergeExpr");
00566 }
00567 
00568 void Expr::verify() const {
00569   if (_preg == NULL) {
00570     error("Expr %#lx: no preg", this);
00571   } else {
00572     _preg->verify();
00573   }
00574   //if (_node) _node->verify();
00575 //  if (unlikelyScope) unlikelyScope->verify();
00576 }
00577   
00578 void KlassExpr::verify() const {
00579   Expr::verify();
00580   _klass->verify();
00581   if (!_klass->is_klass()) error("KlassExpr %#lx: _klass %#lx isn't a klass", this, _klass);
00582 }
00583 
00584 void BlockExpr::verify() const {
00585   Expr::verify();
00586   if (_blockScope != preg()->creationScope()) 
00587     error("BlockExpr %#lx: inconsistent parent scope", this, _blockScope, preg()->creationScope());
00588 }
00589 
00590 void ConstantExpr::verify() const {
00591   Expr::verify();
00592   _c->verify();
00593 }
00594 
00595 void MergeExpr::verify() const {
00596   GrowableArray<Node*> nodes(10);
00597   for (int i = 0; i < exprs->length(); i++) {
00598     Expr* e = exprs->at(i);
00599     e->verify();
00600     if (e->isMergeExpr()) error("MergeExpr %#lx contains nested MergeExpr %#lx", this, e);
00601     Node* n = e->node();
00602     if (n) {
00603       if (nodes.contains(n)) error("MergeExpr %#lx contains 2 expressions with same node %#lx", this, n);
00604       nodes.append(n);
00605     }
00606   }
00607   Expr::verify();
00608 }
00609 
00610 void ContextExpr::verify()  const {
00611   Expr::verify();
00612 }
00613 
00614 
00615 ExprStack::ExprStack(InlinedScope* scope, int size) : GrowableArray<Expr*>(size) {
00616   _scope = scope;
00617 }
00618 
00619 
00620 void ExprStack::push(Expr* expr, InlinedScope* currentScope, int bci) {
00621   assert(!expr->isContextExpr(), "shouldn't push contexts");
00622   // Register expression e for bci
00623   currentScope->setExprForBCI(bci, expr);
00624   // Set r's startBCI if it is an expr stack entry and not already set,
00625   // currentScope is the scope doing the push.
00626   PReg* r = expr->preg();
00627   if (r->isSAPReg()) {
00628     SAPReg* sr = (SAPReg*)r;
00629     if (sr->scope() == _scope) {
00630       if (sr->begBCI() == IllegalBCI)
00631         sr->_begBCI = sr->creationStartBCI = _scope->bci();
00632     } else {
00633       assert(sr->scope()->isSenderOf(_scope), "preg scope too low");
00634     }
00635   }
00636   GrowableArray<Expr*>::push(expr);
00637 }
00638 
00639 
00640 void ExprStack::push2nd(Expr* expr, InlinedScope* currentScope, int bci) {
00641   assert(!expr->isContextExpr(), "shouldn't push contexts");
00642   // Register expression e for current BCI.
00643   currentScope->set2ndExprForBCI(bci, expr);
00644   // Set r's startBCI if it is an expr stack entry and not already set,
00645   // currentScope is the scope doing the push.
00646   PReg* r = expr->preg();
00647   if (r->isSAPReg()) {
00648     SAPReg* sr = (SAPReg*)r;
00649     if (sr->scope() == _scope) {
00650       if (sr->begBCI() == IllegalBCI)
00651         sr->_begBCI = sr->creationStartBCI = _scope->bci();
00652     } else {
00653       assert(sr->scope()->isSenderOf(_scope), "preg scope too low");
00654     }
00655   }
00656   GrowableArray<Expr*>::push(expr);
00657 }
00658 
00659 
00660 void ExprStack::assign_top(Expr* expr) {
00661   assert(!expr->isContextExpr(), "shouldn't push contexts");
00662   GrowableArray<Expr*>::at_put(len - 1, expr);
00663 }
00664 
00665 
00666 Expr* ExprStack::pop() {
00667   Expr* e = GrowableArray<Expr*>::pop();
00668   PReg* r = e->preg();
00669   if (r->isSAPReg()) {
00670     SAPReg* sr = (SAPReg*)r;
00671     if (sr->scope() == _scope) {
00672       // endBCI may be assigned several times
00673       int newBCI =
00674         _scope->bci() == EpilogueBCI ? _scope->nofBytes() - 1 : _scope->bci();
00675       if (bciLT(sr->endBCI(), newBCI)) sr->_endBCI = newBCI;
00676     } else {
00677       assert(sr->scope()->isSenderOf(_scope), "preg scope too low");
00678     }
00679   }
00680   return e;
00681 }
00682 
00683 
00684 void ExprStack::pop(int nofExprsToPop) {
00685   for (int i = 0; i < nofExprsToPop; i++) pop();
00686 }
00687 
00688 
00689 void ExprStack::print() {
00690   const int len = length();
00691   for (int i = 0; i < len; i++) { 
00692     lprintf("[TOS - %2d]:  ", len - i - 1);
00693     at(i)->print();
00694   }
00695 }
00696 
00697   
00698 # endif

Generated on Mon Oct 9 13:37:09 2006 for Strongtalk VM by  doxygen 1.4.7