* Bugfix: InstrucIter no longer used for int_function iteration.
[dyninst.git] / dyninstAPI / src / baseTramp.C
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: baseTramp.C,v 1.59 2007/12/11 20:22:06 bill Exp $
43
44 #include "dyninstAPI/src/baseTramp.h"
45 #include "dyninstAPI/src/miniTramp.h"
46 #include "dyninstAPI/src/instP.h"
47 #include "dyninstAPI/src/addressSpace.h"
48 #include "dyninstAPI/src/rpcMgr.h"
49 #include "dyninstAPI/src/registerSpace.h"
50 #include "dyninstAPI/src/ast.h"
51 #include "dyninstAPI/src/dyn_thread.h"
52 #include "dyninstAPI/h/BPatch.h"
53 #include "debug.h"
54 #include "process.h"
55
56 #if defined(os_aix)
57   extern void resetBRL(process *p, Address loc, unsigned val); //inst-power.C
58   extern void resetBR( process *p, Address loc);               //inst-power.C
59 #endif
60
61 // Normal constructor
62 baseTrampInstance::baseTrampInstance(baseTramp *tramp,
63                                      multiTramp *multi) :    
64     generatedCodeObject(),
65     trampAddr_(0), // Unallocated
66     trampSize_(0),
67     trampPostOffset(0),
68     saveStartOffset(0),
69     saveEndOffset(0),
70     restoreStartOffset(0),
71     restoreEndOffset(0),
72     baseT(tramp),
73     multiT(multi),
74     genVersion(0),
75     alreadyDeleted_(false)
76 {
77 }
78
79 // Fork constructor
80 baseTrampInstance::baseTrampInstance(const baseTrampInstance *parBTI,
81                                      baseTramp *cBT,
82                                      multiTramp *cMT,
83                                      process *child) :
84     generatedCodeObject(parBTI, child),
85     trampAddr_(parBTI->trampAddr_),
86     trampPostOffset(parBTI->trampPostOffset),
87     saveStartOffset(parBTI->saveStartOffset), 
88     saveEndOffset(parBTI->saveEndOffset),
89     restoreStartOffset(parBTI->restoreStartOffset), 
90     restoreEndOffset(parBTI->restoreEndOffset),
91     baseT(cBT),
92     multiT(cMT),
93     genVersion(parBTI->genVersion),
94     alreadyDeleted_(parBTI->alreadyDeleted_)
95 {
96     // Register with parent
97     cBT->instances.push_back(this);
98     // And copy miniTrampInstances
99     for (unsigned i = 0; i < parBTI->mtis.size(); i++) {
100         miniTramp *cMini = NULL;
101
102         cMini = parBTI->mtis[i]->mini->getInheritedMiniTramp(child);
103
104         assert(cMini);
105         miniTrampInstance *newMTI = new miniTrampInstance(parBTI->mtis[i],
106                                                           this,
107                                                           cMini,
108                                                           child);
109         mtis.push_back(newMTI);
110     }
111 }
112
113 baseTrampInstance::~baseTrampInstance() {
114     // What about mtis?
115     for (unsigned i = 0; i < mtis.size(); i++)
116         delete mtis[i];
117
118     if (!alreadyDeleted_ && baseT) {
119         baseT->unregisterInstance(this);
120     }
121 }
122
123 void baseTramp::unregisterInstance(baseTrampInstance *inst) {
124     for (unsigned i = 0; i < instances.size(); i++) {
125         if (instances[i] == inst) {
126             instances.erase(i, i);
127             return;
128         }
129     }
130 }
131
132 #define PRE_TRAMP_SIZE 4096
133 #define POST_TRAMP_SIZE 4096
134
135 baseTramp::baseTramp(instPoint *iP, callWhen when) :
136     preSize(0),
137     postSize(0),
138     saveStartOffset(0),
139     saveEndOffset(0),
140     guardLoadOffset(0),
141     guardBranchSize(0),
142     costUpdateOffset(0),
143     costSize(0),
144     instStartOffset(0),
145     instSize(0),
146     restoreStartOffset(0),
147     restoreEndOffset(0),
148     trampEnd(0),
149     guardBranchIndex(0),
150     costValueOffset(0),
151     guardTargetIndex(0),
152     cost(0),
153     costAddr(0),
154     clobberedGPR(NULL),
155     clobberedFPR(NULL),
156     totalClobbered(0),
157 #if defined( arch_ia64 )
158     trampGuardFlagAddr( 0 ),
159     trampGuardFlagValue( 0 ),
160     addressRegister( 0 ),
161     valueRegister( 0 ),
162 #endif /* defined( arch_ia64 ) */
163 #if defined( cap_unwind )
164     baseTrampRegion( NULL ),
165 #endif /* defined( cap_unwind ) */
166     instP_(iP),
167     rpcMgr_(NULL),
168     isMerged(false),
169     firstMini(NULL),
170     lastMini(NULL),
171     preTrampCode_(),
172     postTrampCode_(),
173     valid(false),
174     optimized_out_guards(false),
175     guardState_(unset_BTR),
176     suppress_threads_(false),
177     instVersion_(),
178     when_(when)
179 {
180 }
181
182 #if defined( cap_unwind )
183 /* Duplicates the list headed by tail and appends it to head, returning the new end of the list.
184    If head is NULL, returns NULL.  If tail is NULL, returns head. */
185 unw_dyn_region_info_t * appendRegionList( unw_dyn_region_info_t * head,  unw_dyn_region_info_t * tail ) {
186         if( head == NULL ) { return NULL; }
187         if( tail == NULL ) { return head; }
188     
189     unw_dyn_region_info_t * currentRegion = head;
190     unw_dyn_region_info_t * nextRegion = tail;
191     unw_dyn_region_info_t * newRegion = NULL;
192     
193         do {
194                 /* Allocate. */
195                 unsigned int nextRegionSize = _U_dyn_region_info_size( nextRegion->op_count );
196                 newRegion = (unw_dyn_region_info_t *)malloc( nextRegionSize );
197                 assert( newRegion != NULL );
198                 
199                 /* Copy. */
200                 memcpy( newRegion, nextRegion, nextRegionSize );
201                 
202                 /* Link. */
203                 currentRegion->next = newRegion;
204                 
205                 /* Iterate. */
206                 currentRegion = newRegion;
207                 nextRegion = currentRegion->next;
208                 } while( nextRegion != NULL );
209
210     return currentRegion;        
211         } /* end duplicateRegionList() */
212         
213 /* Returns the head of the duplicate list. */
214 unw_dyn_region_info_t * duplicateRegionList( unw_dyn_region_info_t * head ) {
215         if( head == NULL ) { return NULL; }     
216
217         /* Duplicate the head and append the remainder to it. */
218         unsigned int headSize = _U_dyn_region_info_size( head->op_count );
219         unw_dyn_region_info_t * duplicateHead = (unw_dyn_region_info_t *)malloc( headSize );
220         assert( duplicateHead != NULL );
221         memcpy( duplicateHead, head, headSize );
222         
223         appendRegionList( duplicateHead, head->next ); 
224         return duplicateHead;
225         } /* end duplicateRegionList() */
226 #endif /* defined( cap_unwind ) */
227
228 baseTramp::baseTramp(const baseTramp *pt, process *child) :
229     preSize(pt->preSize),
230     postSize(pt->postSize),
231     saveStartOffset(pt->saveStartOffset),
232     saveEndOffset(pt->saveEndOffset),
233     guardLoadOffset(pt->guardLoadOffset),
234     guardBranchSize(pt->guardBranchSize),
235     costUpdateOffset(pt->costUpdateOffset),
236     costSize(pt->costSize),
237     instStartOffset(pt->instStartOffset),
238     instSize(pt->instSize),
239     restoreStartOffset(pt->restoreStartOffset),
240     restoreEndOffset(pt->restoreEndOffset),
241     trampEnd(pt->trampEnd),
242     guardBranchIndex(pt->guardBranchIndex),
243     costValueOffset(pt->costValueOffset),
244     guardTargetIndex(pt->guardTargetIndex),
245     cost(pt->cost),
246     costAddr(pt->costAddr),
247     clobberedGPR(NULL),
248     clobberedFPR(NULL),
249     totalClobbered(pt->totalClobbered),
250 #if defined( arch_ia64 )
251     trampGuardFlagAddr( pt->trampGuardFlagAddr ),
252     trampGuardFlagValue( pt->trampGuardFlagValue ),
253         addressRegister( pt->addressRegister ),
254         valueRegister( pt->valueRegister ),
255 #endif /* defined( arch_ia64 ) */    
256     instP_(NULL),
257     firstMini(NULL),
258     lastMini(NULL),
259     preTrampCode_(pt->preTrampCode_),
260     postTrampCode_(pt->postTrampCode_),
261     valid(pt->valid),
262     optimized_out_guards(false),
263     guardState_(pt->guardState_),
264     suppress_threads_(pt->suppress_threads_),
265     instVersion_(pt->instVersion_),
266     when_(pt->when_)
267 {
268     if (pt->clobberedGPR)
269         assert(0); // Don't know how to copy these
270     if (pt->clobberedFPR)
271         assert(0);
272     
273 #if defined( cap_unwind )
274     baseTrampRegion = duplicateRegionList( pt->baseTrampRegion );
275 #endif /* defined( cap_unwind ) */
276
277     // And copy minis
278     miniTramp *parMini = NULL;
279     miniTramp *childPrev = NULL;
280     miniTramp *childMini = NULL;
281     
282     parMini = pt->firstMini;
283     while (parMini) {
284         childMini = new miniTramp(parMini, this, child);
285         if (childPrev) {
286             childPrev->next = childMini;
287         }
288         else {
289             firstMini = childMini;
290         }
291
292         childMini->prev = childPrev;
293         childPrev = childMini;
294         parMini = parMini->next;
295     }
296     lastMini = childMini;
297
298     rpcMgr_ = NULL;
299     if (pt->rpcMgr_) {
300         rpcMgr_ = child->getRpcMgr();
301     }
302 }
303
304 baseTramp::~baseTramp() {
305     // Delete clobberedGPR and clobberedFPR?
306     // Dunno
307 }
308
309 unsigned baseTrampInstance::get_size_cr() const { 
310     // Odd... especially if there are minitramps in the middle. 
311     // For now return a+b; eventually we'll need a codeRange
312     // that can handle noncontiguous ranges.
313     assert(baseT);
314     Address endAddr = trampPostAddr() + baseT->postSize;
315     return endAddr - get_address_cr();
316 }
317
318 // recursive into miniTramps
319 // If we generated once, we skip most of this as useless.
320 // However, we still go into the miniTramps.
321
322 bool baseTrampInstance::generateCode(codeGen &gen,
323                                      Address baseInMutatee,
324                                      UNW_INFO_TYPE ** unwindRegion) 
325 {
326     inst_printf("baseTrampInstance %p ::generateCode(%p, 0x%x, %d)\n",
327                 this, gen.start_ptr(), baseInMutatee, gen.used());
328     
329     updateMTInstances();
330     
331     if (isEmpty()) {
332         hasChanged_ = false;
333         generated_ = true;
334         return true;
335     }
336
337
338     if (baseT->instP()) {
339        //iRPCs already have this set
340        gen.setPoint(baseT->instP());
341        gen.setRegisterSpace(registerSpace::actualRegSpace(baseT->instP(), baseT->when_));
342     }
343     
344     if (BPatch::bpatch->isMergeTramp()) {
345         // /* DEBUG */ fprintf( stderr, "%s[%d]: generating code in-the-line\n", __FILE__, __LINE__ );
346         return generateCodeInlined(gen, baseInMutatee, unwindRegion);
347     }
348     else {
349         // /* DEBUG */ fprintf( stderr, "%s[%d]: generating code out-of-line\n", __FILE__, __LINE__ );
350         return generateCodeOutlined(gen, baseInMutatee, unwindRegion);
351     }
352
353 }
354
355 bool baseTrampInstance::generateCodeOutlined(codeGen &gen,
356                                              Address baseInMutatee,
357                                              UNW_INFO_TYPE **unwindRegion) {    
358     if (!generated_) {
359         baseT->generateBT(gen);
360         
361         // if in-line...
362         // For now BTs are in-lined; they could be made out-of-line
363         
364         assert(baseT);
365         if (!baseT->valid) return false;
366         
367         trampAddr_ = gen.currAddr(baseInMutatee);
368     }
369     else {
370         // We better be where we were...
371         assert(trampAddr_ == gen.currAddr(baseInMutatee));
372     }
373     
374     saveStartOffset = baseT->saveStartOffset;
375     saveEndOffset = baseT->saveEndOffset;
376     restoreStartOffset = baseT->restoreStartOffset;
377     restoreEndOffset = baseT->restoreEndOffset;
378
379     codeBufIndex_t preIndex = gen.getIndex();
380     unsigned preStart = gen.used();
381     
382     // preTramp
383     if (!generated_) {
384         // Only copy if we haven't been here before. 
385         gen.copy(baseT->preTrampCode_);
386     }
387     else {
388         gen.moveIndex(baseT->preSize);
389     }
390     //inst_printf("offset now %d\n", gen.used());
391     //unsigned preEnd = offset;
392     
393 #if defined( cap_unwind )
394     // This should become preTrampRegion, if the basetramp stops using only one region.
395     /* appendRegionList() returns the last valid region it duplicated.
396        This leaves unwindRegion pointing to the end of the list. */
397     * unwindRegion = appendRegionList( * unwindRegion, baseT->baseTrampRegion );
398 #endif /* defined( cap_unwind ) */
399     
400     // miniTramps
401     // If we go backwards, life gets much easier because each miniTramp
402     // needs to know where to jump to (if we're doing out-of-line). 
403     // Problem is, we can't if we're doing in-line. 
404     
405     // So we'll get to it later.
406     
407     // We're using a pre-generated code template and copying it in -
408     // which means the register information is _all_ screwed up.
409     // For now, we cheese out by assuming everything is saved (well, 
410     // it is) and swapping register spaces. The baseTramp keeps one,
411     // since it needs to know where registers are saved.
412     registerSpace *curRegSpace = gen.rs();
413
414     gen.setRegisterSpace(registerSpace::actualRegSpace(baseT->instP(), baseT->when_));
415     
416     for (unsigned miter = 0; miter < mtis.size(); miter++) {
417         mtis[miter]->generateCode(gen, baseInMutatee, unwindRegion);
418         // Will increment offset if it writes to baseInMutator;
419         // if in-lined each mini will increment offset.
420         inst_printf("mti %d, offset %d\n", miter, gen.used());
421     }
422     gen.setRegisterSpace(curRegSpace);
423
424     
425     codeBufIndex_t postIndex = gen.getIndex();
426     unsigned postStart = gen.used();
427     
428       
429     if (!generated_) {
430         gen.copy(baseT->postTrampCode_);
431     }
432     else {
433         gen.moveIndex(baseT->postSize);
434     }
435
436     //inst_printf("post, offset %d\n", gen.used());
437     
438     if (!generated_) {
439         trampPostOffset = postStart - preStart;
440     }
441     else {
442         assert(trampPostOffset == (postStart - preStart));
443     }
444
445 #if defined( cap_unwind )
446         // Since the basetramp (currently) uses only one region, don't add it into the list again.
447         /* appendRegionList() returns the last valid region it duplicated.
448            This leaves unwindRegion pointing to the end of the list. */
449         // * unwindRegion = appendRegionList( * unwindRegion, baseT->postUnwindRegion );
450 #endif /* defined( cap_unwind ) */
451
452     // trampAddr_ was set above. 
453
454     // Now, we have a lot of relative jumps that need to be fixed.
455     // We've ignored the skipJumps; if there are no miniTramps we
456     // just skip the BT altogether. However, there is the guard jump
457     // and miniTramp jumps
458
459     // Fix the guard branch...
460
461     if (!generated_) {
462         if (baseT->guardBranchIndex) {
463             codeBufIndex_t savedIndex = gen.getIndex();
464             gen.setIndex(preIndex + baseT->guardBranchIndex);
465             int disp = codeGen::getDisplacement(preIndex + baseT->guardBranchIndex,
466                                                 postIndex + baseT->guardTargetIndex);
467             finalizeGuardBranch(gen, disp);
468             gen.setIndex(savedIndex);
469         }
470         else {
471             assert(baseT->guardBranchIndex == 0);
472             assert(baseT->guardLoadOffset == 0);
473             assert(baseT->guardTargetIndex == 0);
474         }
475     }
476     
477     // We just generated all the miniTramps,
478     // so bump versions on the generated instPointInstances
479     generated_ = true;
480     hasChanged_ = false;
481
482     return true;
483 }
484
485 #include "BPatch.h"
486 #include "BPatch_collections.h"
487 bool baseTrampInstance::generateCodeInlined(codeGen &gen,
488                                             Address baseInMutatee,
489                                             UNW_INFO_TYPE **unwindRegion) {
490     if (!hasChanged() && generated_) {
491         assert(gen.currAddr(baseInMutatee) == trampAddr_);
492         gen.moveIndex(trampSize_);
493         return true;
494     }
495
496     // Experiment: use AST-based code generation....
497
498     // We're generating something like so:
499     //
500     // <Save state>
501     // <If>
502     //    <compare>
503     //      <load>
504     //        <add>
505     //          <tramp guard addr>
506     //          <multiply>
507     //            <thread index>
508     //            <sizeof (int)>
509     //      <0>
510     //    <sequence>
511     //      <store>
512     //        <... tramp guard addr>
513     //        <1>
514     //      <mini tramp sequence>
515     //      <store>
516     //        <... tramp guard addr>
517     //        <0>
518     // <Cost section>
519     // <Load state>
520
521
522     // Break it down...
523     // <Save state>
524     //   -- TODO: an AST for saves that knows how many registers
525     //      we're using...
526
527     // Now we start building up the ASTs to generate. Let's get the
528     // pieces.
529
530     // Specialize for the instPoint...
531         
532     gen.setRegisterSpace(registerSpace::actualRegSpace(baseT->instP(), baseT->when_));
533
534     pdvector<AstNodePtr> miniTramps;
535     for (unsigned miter = 0; miter < mtis.size(); miter++) {
536       miniTramps.push_back(mtis[miter]->mini->ast_->getAST());
537       // And nuke the hasChanged flag in there - we don't generate
538       // code that way
539       mtis[miter]->markChanged(false);
540       mtis[miter]->markGenerated(true);
541     }
542     AstNodePtr minis = AstNode::sequenceNode(miniTramps);
543
544     // Let's build the tramp guard addr (if we want it)
545     AstNodePtr threadIndex;
546     AstNodePtr trampGuardAddr;
547     if (baseT->guarded() &&
548         minis->containsFuncCall() &&
549         (proc()->trampGuardAST() != AstNodePtr())) {
550         // If we don't have a function call, then we don't
551         // need the guard....
552
553         // Now, the guard flag. 
554         // If we're multithreaded, we need to index off
555         // the base address.
556         if (!baseT->threaded()) {
557             // ...
558         }
559         else if (gen.thread()) {
560             // Constant override...
561             threadIndex = AstNode::operandNode(AstNode::Constant,
562                                                (void *)gen.thread()->get_index());
563         }
564         else {
565             // TODO: we can get clever with this, and have the generation of
566             // the thread index depend on whether gen has a thread defined...
567             // For that, we'd need an AST thread index node. Just something
568             // to think about. Maybe a child of funcNode?
569             threadIndex = AstNode::threadIndexNode();
570         }
571         
572         if (threadIndex) {
573             trampGuardAddr = AstNode::operandNode(AstNode::DataIndir,
574                                                   AstNode::operatorNode(plusOp,
575                                                                         AstNode::operatorNode(getAddrOp,
576                                                                                               proc()->trampGuardAST()),
577                                                                         AstNode::operatorNode(timesOp,
578                                                                                               threadIndex,
579                                                                                               AstNode::operandNode(AstNode::Constant, 
580                                                                                                                    (void *)sizeof(unsigned)))));
581             /* At the moment, we can't directly specify the fact
582                that we're loading 4 bytes instead of a normal
583                (address-width) word. */
584             trampGuardAddr->setType( BPatch::getBPatch()->builtInTypes->findBuiltInType( "unsigned int" ) );
585         }
586         else {
587             trampGuardAddr = proc()->trampGuardAST();
588         }
589     }
590
591
592     AstNodePtr baseTrampSequence;
593     pdvector<AstNodePtr > baseTrampElements;
594
595     if (trampGuardAddr) {
596         // First, set it to 0
597         baseTrampElements.push_back(AstNode::operatorNode(storeOp, 
598                                                           trampGuardAddr,
599                                                           AstNode::operandNode(AstNode::Constant,
600                                                                                (void *)0)));
601     }
602     
603     // Run the minitramps
604     baseTrampElements.push_back(minis);
605     
606     // Cost code...
607     //
608     
609     if (trampGuardAddr) {
610         // And set the tramp guard flag to 1
611         baseTrampElements.push_back(AstNode::operatorNode(storeOp,
612                                                           trampGuardAddr,
613                                                           AstNode::operandNode(AstNode::Constant,
614                                                                                (void *)1)));
615     }
616
617     baseTrampSequence = AstNode::sequenceNode(baseTrampElements);
618
619     AstNodePtr baseTramp;
620
621     // If trampAddr is non-NULL, then we wrap this with an IF. If not, 
622     // we just run the minitramps.
623     if (trampGuardAddr == NULL) {
624         baseTramp = baseTrampSequence;
625         baseTrampSequence.reset();
626     }
627     else {
628         // Oh, boy. 
629 #if 0
630         baseTramp = AstNode::operatorNode(ifOp,
631                                           AstNode::operatorNode(eqOp,
632                                                                 trampGuardAddr,
633                                                                 AstNode::operandNode(AstNode::Constant, (void *)1)),
634                                           baseTrampSequence);
635 #endif
636         // Short form of the above
637         baseTramp = AstNode::operatorNode(ifOp,
638                                           trampGuardAddr,
639                                           baseTrampSequence);
640     }
641
642
643 #if defined(cap_unwind)
644       if (baseT->baseTrampRegion != NULL) {
645           free(baseT->baseTrampRegion);
646           baseT->baseTrampRegion = NULL;
647       }
648 #endif
649
650     trampAddr_ = gen.currAddr();
651
652     // Sets up state in the codeGen object (and gen.rs())
653     // that is later used when saving and restoring. This
654     // MUST HAPPEN BEFORE THE SAVES, and state should not
655     // be reset until AFTER THE RESTORES.
656     baseTramp->initRegisters(gen);
657     saveStartOffset = gen.used();
658     baseT->generateSaves(gen, gen.rs());
659     saveEndOffset = gen.used();
660     bool retval = true;
661
662     if (!baseTramp->generateCode(gen, false)) {
663         fprintf(stderr, "Gripe: base tramp creation failed\n");
664         retval = false;
665     }
666
667
668     trampPostOffset = gen.used();
669     restoreStartOffset = 0;
670     baseT->generateRestores(gen, gen.rs());
671     restoreEndOffset = gen.used() - trampPostOffset;
672     trampSize_ = gen.currAddr() - trampAddr_;
673
674     // And now to clean up after us
675     //if (minis) delete minis;
676     //if (trampGuardAddr) delete trampGuardAddr;
677     //if (baseTrampSequence) delete baseTrampSequence;
678     //if (baseTramp) delete baseTramp;
679
680 #if defined( cap_unwind )
681         /* At the moment, AST nodes can /not/ modify unwind state.  (Whoo-hoo!)
682            Therefore, to account for them, we just need to know how much code
683            they generated... */
684     Address endSaves = saveEndOffset + gen.startAddr();
685     Address beginRestores = trampPostOffset + gen.startAddr();
686     baseT->baseTrampRegion->insn_count += ((beginRestores - endSaves)/16) * 3;
687     
688         /* appendRegionList() returns the last valid region it duplicated.
689            This leaves unwindRegion pointing to the end of the list. */
690     * unwindRegion = appendRegionList( * unwindRegion, baseT->baseTrampRegion );
691 #endif /* defined( cap_unwind ) */
692
693     generated_ = true;
694     hasChanged_ = false;
695
696     return retval;
697 }
698
699 bool baseTrampInstance::installCode() {
700     // All BTIs are in-lined, so this has no direct work to do;
701     // call into minitramps and then ensure that all jumps
702     // are correct.
703
704     for (unsigned i = 0; i < mtis.size(); i++) {
705         mtis[i]->installCode();
706     }
707
708     installed_ = true;
709     return true;
710 }
711
712 void baseTrampInstance::generateBranchToMT(codeGen &gen) {
713     // Finally, from the BT to miniTramps
714     if (baseT->firstMini) {
715         Address firstTarget = baseT->firstMini->getMTInstanceByBTI(this)->trampBase;
716         // If MT is out-of-line...
717 #if defined(os_aix) 
718         // AIX uses funky branches
719         instruction::generateInterFunctionBranch(gen,
720                                                  trampPreAddr() + baseT->instStartOffset,
721                                                  firstTarget);
722 #else
723         instruction::generateBranch(gen,
724                                     trampPreAddr() + baseT->instStartOffset,
725                                     firstTarget);
726 #endif
727         // Safety: make sure we didn't stomp on anything important.
728         assert(gen.used() <= baseT->instSize);
729     }
730     else {
731         // We must have nuked the miniTramps...
732         assert(baseT->lastMini == NULL);
733         // And clear out ze branch-y
734         gen.fill(baseT->instSize, codeGen::cgNOP);
735     }
736 }
737
738 AddressSpace *baseTramp::proc() const { 
739   if (instP_)
740     return instP_->proc();
741   if (rpcMgr_)
742     return rpcMgr_->proc();
743   return NULL;
744 }
745
746 Address baseTramp::origInstAddr() {
747   // Where we would be if we weren't relocated, if we were in the
748   // original spot, etc. etc. etc.  Base tramp instances aren't
749   // necessarily sorted by anything meaningful, so check the long
750   // way.
751   
752   // TODO: a post tramp _should_ return the next addr, but hey...
753
754   if (!instP_) {
755     assert(rpcMgr_ != NULL);
756     return 0;
757   }
758   
759   return instP()->addr();
760 }
761
762 bool baseTramp::inBasetramp( Address addr ) {
763   for (unsigned i = 0; i < instances.size(); i++) {
764     if (instances[i]->isInInstance(addr))
765       return true;
766   }
767   return false;
768 }
769
770
771 bool baseTramp::inSavedRegion (Address addr) {
772   for (unsigned i = 0; i < instances.size(); i++) {
773     if (instances[i]->isInInstru(addr))
774       return true;
775   }
776   return false;
777 }
778
779 #if 0
780 void
781 baseTramp::updateTrampCost(int trampCost) {
782 #ifndef alpha_dec_osf4_0 /* XXX We don't calculate cost yet on Alpha */
783     cost = cost + trampCost;
784     if (cost < 0) cost = 0;
785
786     char costInsn[40];
787     Address csize = 0;
788     Address caddr = proc()->getObservedCostAddr();    
789     if (caddr == 0) {
790       bpwarn("Observed cost address 0, skipping cost calculation");
791       return;
792     }
793     emitVupdate(updateCostOp, cost, 0, caddr, costInsn, csize, false);
794     proc()->writeDataSpace((caddr_t)costAddr, csize, costInsn);
795 #endif
796 }
797 #endif
798
799 // Add a miniTramp to the appropriate place: at the start or end of
800 // its instPoint minis.
801 bool baseTramp::addMiniTramp(miniTramp *newMT, callOrder order) {
802     if (firstMini == NULL) {
803         // Life is easy...
804         assert(lastMini == NULL);
805         firstMini = lastMini = newMT;
806     }
807     else {
808       if (order == orderFirstAtPoint) {
809         // orderFirstAtPoint, post-instrumentation
810         assert(firstMini);
811         firstMini->prev = newMT;
812         newMT->next = firstMini;
813         firstMini = newMT;
814       }
815       else {
816         // orderLastAtPoint, post-instrumentation
817         assert(lastMini);
818         lastMini->next = newMT;
819         newMT->prev = lastMini;
820         lastMini = newMT;
821       }
822     }
823
824     // Push to baseTrampInstances
825     for (unsigned i = 0; i < instances.size(); i++) {
826         instances[i]->updateMTInstances();
827     }
828
829     assert(firstMini != NULL);
830     assert(lastMini != NULL);
831
832     instVersion_++;
833
834     return true;
835 }
836
837 bool baseTrampInstance::isInInstance(Address pc) {
838     assert(baseT);
839     if (trampPreAddr() == 0) {
840         // Not allocated yet...
841         return false;
842     }
843
844     if (trampSize_) { // Inline
845         return ((pc >= trampAddr_) &&
846                 (pc < (trampAddr_ + trampSize_)));
847     }
848
849     return (pc >= trampPreAddr() &&
850             pc < (trampPostAddr() + baseT->postSize));
851 }
852
853 bool baseTrampInstance::isInInstru(Address pc) {
854     assert(baseT);
855     return (pc >= (trampPreAddr() + saveStartOffset) &&
856             pc < (trampPostAddr() + restoreEndOffset));
857 }
858
859 instPoint *baseTrampInstance::findInstPointByAddr(Address /*addr*/) {
860     assert(baseT);
861     return baseT->instP_;
862 }
863
864 bool baseTrampInstance::isEmpty() {
865     return (mtis.size() == 0);
866 }
867
868 // If all miniTramps are removed, nuke the baseTramp
869 // Chains to multiTramp->deleteIfEmpty
870 // But for now puts in the "skip" jump if all miniTramps are removed
871 void baseTramp::deleteIfEmpty() {
872     if (firstMini != NULL) {
873         assert(lastMini != NULL);
874         return;
875     }
876
877     assert(lastMini == NULL);
878
879     // This deletion handles _only_ the logical side of things;
880     // don't touch the Instances (they stick around until we
881     // can garbage collect the code).
882
883     // Clean up this guy
884     if (instP()) {
885         if (instP()->preBaseTramp() == this)
886             instP()->preBaseTramp_ = NULL;
887         
888         if (instP()->postBaseTramp() == this)
889             instP()->postBaseTramp_ = NULL;
890       
891       if (instP()->targetBaseTramp() == this)
892          instP()->targetBaseTramp_ = NULL;
893     }
894
895     instP_ = NULL;
896
897     instances.clear();
898     delete this;
899 }
900
901 // Where should the minitramps jump back to?
902 Address baseTrampInstance::miniTrampReturnAddr() {
903     // Might want to make an offset, but for now we go straight back.
904     return trampPostAddr();
905 }
906
907 bool baseTramp::isConservative() {
908   if (instP() && instP()->getPointType() == otherPoint)
909     return true;
910   if (rpcMgr_)
911     return true;
912   return false;
913 }
914
915 bool baseTramp::isCallsite() {
916     if (instP() && instP()->getPointType() == callSite)
917         return true;
918
919     return false;
920 }
921
922 bool baseTramp::isEntryExit() {
923   if (instP() && ((instP()->getPointType() == functionEntry) ||
924                 (instP()->getPointType() == functionExit)))
925     return true;
926   
927   return false;
928 }
929
930 bool baseTrampInstance::shouldGenerate() {
931     miniTramp *mini = baseT->firstMini;
932     // No miniTramps, no work, no bother.
933     return (mini != NULL);
934 }
935
936 unsigned baseTrampInstance::maxSizeRequired() {
937     assert(this);
938
939     updateMTInstances();
940
941     if (isEmpty())
942         return 0;
943
944     unsigned size = 0;
945
946
947     if (BPatch::bpatch->isMergeTramp()) {
948         // TEMPORARY HACK!!! WILL NEED TO GET SOMETHING BETTER THAT
949         // FIGURES OUT THE SIZE FOR THE BASE TRAMP WITHOUT MAKING IT
950         // SO THE MINI-TRAMP IS GENERATED AFTER THE BASE TRAMP,
951         // FOR NOW, WE'LL JUST ERR ON THE SAFE SIDE FOR THE BUFFER
952                 size += 100; // For the base tramp
953     }
954     else {
955                 if (!baseT->valid)
956             baseT->generateBT(codeGen::baseTemplate);
957         
958                 assert(baseT->valid);
959                 size += baseT->preSize + baseT->postSize;
960     }
961
962
963     for (unsigned i = 0; i < mtis.size(); i++)
964       size += mtis[i]->maxSizeRequired();
965     
966 #if defined(arch_ia64)
967         size *= 8; // Enormous on this platform...
968 #endif
969     inst_printf("Pre-size %d, post-size %d, total size %d\n",
970                 baseT->preSize,
971                 baseT->postSize,
972                 size);
973     return size;
974 }
975
976 // Should have some mechanism to understand if we need
977 // to clear this out and start over... this is a lot
978 // of wasted work.
979 void baseTrampInstance::updateMTInstances() {
980     unsigned oldNum = mtis.size();
981     mtis.clear();
982
983     miniTramp *mini = baseT->firstMini;
984     while (mini) {
985         miniTrampInstance *mti = mini->getMTInstanceByBTI(this);
986         mtis.push_back(mti);
987         if (mti->hasChanged()) {
988             hasChanged_ = true;
989         }
990         mini = mini->next;
991     }
992
993     // If we now have an MTI, we've changed (as previously
994     // we wouldn't bother generating code)
995     if ((oldNum == 0) &&
996         (mtis.size() != 0)) {
997         hasChanged_ = true;
998     }
999     inst_printf("BTI %p update: %d originally, %d now\n",
1000                 this, oldNum, mtis.size());
1001 }
1002
1003 baseTrampInstance *baseTramp::findOrCreateInstance(multiTramp *multi) {
1004     // First, check to see if we have one...
1005     for (unsigned i = 0; i < instances.size(); i++) {
1006         if (instances[i]->multiT == multi)
1007             return instances[i];
1008     }
1009     baseTrampInstance *newInst = new baseTrampInstance(this, multi);
1010     instances.push_back(newInst);
1011     return newInst;
1012 }
1013
1014 bool baseTramp::doOptimizations() 
1015 {
1016    miniTramp *cur_mini = firstMini;
1017    bool hasFuncCall = false;
1018
1019    if (!BPatch::bpatch->isMergeTramp())
1020       return false;
1021
1022    while (cur_mini) {
1023        if (cur_mini->ast_->containsFuncCall()) {
1024            hasFuncCall = true;
1025            break;
1026        }
1027        cur_mini = cur_mini->next;
1028    }
1029    
1030    if (!hasFuncCall) {
1031       guardState_ = unset_BTR;
1032       setRecursive(true, true);
1033       optimized_out_guards = true;
1034       setThreaded(false);
1035       return true;
1036    }
1037    return false;
1038 }
1039
1040 void baseTramp::setRecursive(bool trampRecursive, bool force) {
1041    if (force) {
1042       guardState_ = trampRecursive ? recursive_BTR : guarded_BTR;
1043       return;
1044    }
1045     if (trampRecursive) {
1046         if (guardState_ == unset_BTR)
1047             guardState_ = recursive_BTR;
1048         else {
1049             if (guardState_ == guarded_BTR) {
1050                 guardState_ = recursive_BTR; //ccw 24 jan 2006 
1051             }
1052         }
1053     }
1054     else {
1055         if (guardState_ == unset_BTR) {
1056             guardState_ = guarded_BTR;
1057         }
1058         else {
1059             if (guardState_ == recursive_BTR) {
1060                if (!optimized_out_guards)
1061                   //                  cerr << "WARNING: collision between pre-existing recursive miniTramp and new miniTramp, now guarded!" << endl;
1062                 guardState_ = guarded_BTR;
1063             }
1064         }
1065     }
1066 }
1067
1068 bool baseTramp::getRecursive() const {
1069     switch (guardState_) {
1070     case unset_BTR:
1071         assert(0);
1072         return false;
1073         break;
1074     case recursive_BTR:
1075         return true;
1076         break;
1077     case guarded_BTR:
1078         return false;
1079         break;
1080     }
1081     assert(0);
1082     return false;
1083 }
1084
1085 // Generates an instruction buffer that holds the base tramp
1086 bool baseTramp::generateBT(codeGen &baseGen) {
1087
1088   if (valid && !(BPatch::bpatch->isMergeTramp())){
1089       return true; // May be called multiple times
1090     }
1091   else
1092     {
1093       preTrampCode_.invalidate();
1094       postTrampCode_.invalidate();
1095
1096 #if defined(cap_unwind)
1097       if (baseTrampRegion != NULL) {
1098           free(baseTrampRegion);
1099           baseTrampRegion = NULL;
1100       }
1101 #endif
1102     }
1103     //inst_printf("Generating a baseTramp, guarded %d\n", guardState_);
1104     // Make a base tramp. That is, a save/restore pair that includes the base
1105     // tramp guard. 
1106     // Also populate member vrbles:
1107     // preSize, postSize;
1108     // saveStartOffset
1109     // saveEndOffset
1110     // guardLoadOffset
1111     // guardBranchOffset
1112     // ..  and guardBranchSize
1113     // costUpdateOffset
1114     // instStartOffset
1115     // ... instSize is set by the miniTramp
1116
1117     // restoreStartOffset
1118     // guardTargetOffset
1119     // restoreEndOffset
1120     // trampEnd
1121     
1122     /*
1123      * This is what a base tramp looks like:
1124      offset     insn                 cost
1125
1126      ////////////////// X86 ///////////////////
1127
1128      PRE:
1129      0:         pushfd               5
1130      1:         pushad               9
1131      2:         push ebp             1
1132      3:         mov esp, ebp         1
1133      6:         subl esp, 0x80       1
1134      ... multithread code (must go before tramp guard)
1135      ... tramp guard
1136
1137      12:        start of minitramp   ??
1138
1139      POST:
1140      0:         add <costaddr> <cost> 3
1141      10:        leave                 3
1142      11:        popad                 14
1143      12:        popfd                 5
1144      //////////////////////////////////////////
1145
1146      ////////////////POWER/////////////////////
1147      0:         stu   (make stack frame)
1148      ....
1149      
1150      */
1151
1152     // We should catch if we're regenerating
1153     
1154         // Set up the registerSpace for the baseGen structure
1155         // If we're calling generateBT, we're out-of-lining... so 
1156         // we can't take advantage of instr-unused registers
1157   if (instP()) 
1158      baseGen.setRegisterSpace(registerSpace::actualRegSpace(instP(), when_));
1159         
1160
1161   assert(preTrampCode_ == NULL);
1162   assert(postTrampCode_ == NULL);
1163   preTrampCode_.applyTemplate(baseGen);
1164   preTrampCode_.allocate(PRE_TRAMP_SIZE);
1165   postTrampCode_.applyTemplate(baseGen);
1166   postTrampCode_.allocate(POST_TRAMP_SIZE);
1167
1168   preTrampCode_.setAddrSpace(proc());
1169   postTrampCode_.setAddrSpace(proc());
1170   
1171   preTrampCode_.setRegisterSpace(baseGen.rs());
1172   
1173   
1174   saveStartOffset = preTrampCode_.used();
1175   inst_printf("Starting saves: offset %d\n", saveStartOffset);
1176
1177     generateSaves(preTrampCode_, preTrampCode_.rs());
1178
1179     // Done with save
1180     saveEndOffset = preTrampCode_.used();
1181     inst_printf("Starting MT: offset %d\n", saveEndOffset);
1182
1183
1184   // Multithread
1185     generateMTCode(preTrampCode_, preTrampCode_.rs());
1186
1187     // Guard code
1188     guardLoadOffset = preTrampCode_.used();
1189     inst_printf("Starting guard: offset %d\n", guardLoadOffset);
1190     if (guarded() &&
1191         generateGuardPreCode(preTrampCode_,
1192                              guardBranchIndex,
1193                              preTrampCode_.rs())) {
1194         // Cool.
1195     }
1196     else {
1197         // No guard...
1198         guardBranchIndex = 0;
1199         guardLoadOffset = 0;
1200     }
1201     
1202     
1203
1204     costUpdateOffset = preTrampCode_.used();
1205
1206     inst_printf("Starting cost: offset %d\n", costUpdateOffset);
1207
1208     // We may not want cost code... for now if we're an iRPC tramp
1209     // In the future, this may change
1210     // In general, instrumentation wants cost code. The minitramps may be 
1211     // null, but we put in the stub anyway.
1212     if (rpcMgr_ == NULL &&
1213         generateCostCode(preTrampCode_, costValueOffset, preTrampCode_.rs())) {
1214         costSize = preTrampCode_.used() - costUpdateOffset;
1215         // If this is zero all sorts of bad happens
1216         assert(costValueOffset);
1217     }
1218     else {
1219         costSize = 0;
1220         costValueOffset = 0;
1221     }
1222
1223     instStartOffset = preTrampCode_.used();
1224     preSize = preTrampCode_.used();
1225     inst_printf("Starting inst: offset %d\n", instStartOffset);
1226     inst_printf("preSize is: %d\n", preSize);    
1227
1228 // IA-64...
1229         if (preTrampCode_.rs() != baseGen.rs()) {
1230                 // Grab any updates that were made
1231                 baseGen.setRegisterSpace(preTrampCode_.rs());
1232         }
1233
1234     postTrampCode_.setRegisterSpace(baseGen.rs());
1235
1236
1237     // Post...
1238     // Guard redux
1239     if (guarded())
1240         generateGuardPostCode(postTrampCode_, 
1241                               guardTargetIndex,
1242                               postTrampCode_.rs());
1243     else
1244         guardTargetIndex = 0;
1245
1246     // Restore registers
1247     restoreStartOffset = postTrampCode_.used();
1248     generateRestores(postTrampCode_, postTrampCode_.rs());
1249
1250 //#if defined(arch_power)
1251 //    baseGen.rs()->setAllLive();
1252 //#endif 
1253
1254     restoreEndOffset = postTrampCode_.used();
1255     //inst_printf("Ending restores: %d\n", restoreEndOffset);
1256
1257     trampEnd = postTrampCode_.used();
1258     postSize = postTrampCode_.used();
1259
1260     valid = true;
1261     preTrampCode_.finalize();
1262     postTrampCode_.finalize();
1263
1264     /*
1265       inst_printf("pre size: %d, post size: %d\n",
1266       preSize, postSize);
1267       inst_printf("saveStart: %d, saveEnd: %d, guardLoad: %d, guardBranch %d, cost %d, inst %d\n",
1268       saveStartOffset,
1269       saveEndOffset,
1270       guardLoadOffset,
1271       guardBranchIndex,
1272       costUpdateOffset,
1273       instStartOffset);
1274       
1275       inst_printf("restoreStart %d, guardTarget %d, restoreEnd %d, trampEnd %d\n",
1276       restoreStartOffset,
1277       guardTargetIndex,
1278       restoreEndOffset,
1279       trampEnd);
1280     */
1281 #if defined( cap_unwind )
1282         /* FIXME: the guard and multitramp code don't yet update the baseTrampRegion
1283            insn_count themselves, so do that here. */
1284 #if defined( arch_ia64 )
1285         baseTrampRegion->insn_count += ( (instStartOffset - saveEndOffset)/ 16 ) * 3;
1286         baseTrampRegion->insn_count += ( (restoreStartOffset - 0)/ 16 ) * 3;
1287 #else
1288 #error How do I know how many instructions are in the jump region?
1289 #endif /* defined( arch_ia64 ) */
1290 #endif /* defined( cap_unwind ) */
1291
1292     return true;
1293 }
1294     
1295 void baseTrampInstance::removeCode(generatedCodeObject *subObject) {
1296     miniTrampInstance *delMTI = dynamic_cast<miniTrampInstance *>(subObject);
1297     multiTramp *delMulti = dynamic_cast<multiTramp *>(subObject);
1298     assert(delMTI || delMulti);
1299
1300     if (delMTI) {
1301         // We lost a miniTramp...
1302         
1303         // Move the MTI from the current list to the deleted list.
1304         for (unsigned i = 0; i < mtis.size(); i++) {
1305             if (mtis[i] == subObject) {
1306                 if (BPatch::bpatch->isMergeTramp()) 
1307                     deletedMTIs.push_back(mtis[i]);
1308                 mtis[i] = mtis.back();
1309                 mtis.pop_back();
1310                 break;
1311             }
1312         }
1313         
1314         // See if this is the last MTI; if so, delete ourselves.
1315         if (isEmpty()) {
1316             // We didn't allocate, so we don't call deleteGenerated...
1317             //proc()->deleteGeneratedCode(this);
1318             multiT->removeCode(this);
1319             // The above call to removeCode may cause all sorts of havoc,
1320             // including regenerating the multiTramp. On the other hand,
1321             // if there are miniTramps left, we effectively stop here.
1322         }
1323         else {
1324             // When we in-line, this will need to change. For now,
1325             // we can always fix jumps by hand
1326             if (BPatch::bpatch->isMergeTramp()) {
1327                 hasChanged_ = true;
1328             }
1329             else {
1330                 // we occasionally see a case where this->trampAddr_ has 
1331                 // already been reset to zero, assume no need to update
1332                 if(trampPreAddr() != 0) {
1333                     codeGen gen(instruction::maxJumpSize());
1334                     generateBranchToMT(gen);
1335                     proc()->writeDataSpace((void *)(trampPreAddr() + baseT->instStartOffset),
1336                                            gen.used(),
1337                                            gen.start_ptr());
1338                 }
1339             }
1340         }
1341     }
1342     else {
1343         assert(delMulti); 
1344         if (multiT != delMulti) {
1345             // Huh. Okay, someone we don't care about any more went away. Nifty.
1346             return;
1347         }
1348         // The multiTramp was just removed. Tell our miniTramps about it;
1349         // if they haven't been attached to a different baseTrampInstance,
1350         // this will remove them.
1351         for (unsigned j = 0; j < mtis.size(); j++) {
1352             mtis[j]->removeCode(this);
1353             if (!BPatch::bpatch->isMergeTramp())
1354                 deletedMTIs.push_back(mtis[j]);
1355         }
1356         mtis.clear();
1357
1358         baseT->unregisterInstance(this);
1359         alreadyDeleted_ = true;
1360     }
1361            
1362 }
1363
1364 bool baseTrampInstance::safeToFree(codeRange *range) {
1365
1366     if (dynamic_cast<baseTrampInstance *>(range) == this)
1367         return false;
1368
1369     // Better not be freeing ourselves if we have sub-mtis left...
1370     assert(isEmpty());
1371
1372     // If the PC is in any of the miniTramps, we're not
1373     // good.
1374     
1375     // I think we can just check all of the MTIs using their
1376     // safeToFree; if we can't free a miniTramp, we can't free
1377     // the baseTramp
1378     for (unsigned i = 0; i < deletedMTIs.size(); i++)
1379         if (!deletedMTIs[i]->safeToFree(range))
1380             return false;
1381
1382     return true;
1383 }
1384
1385 AddressSpace *baseTrampInstance::proc() const {
1386     assert(baseT);
1387     return baseT->proc();
1388 }
1389
1390
1391 void baseTrampInstance::invalidateCode() {
1392     generatedCodeObject::invalidateCode();
1393     trampAddr_ = 0;
1394     trampSize_ = 0;
1395     trampPostOffset = 0;
1396     for (unsigned i = 0; i < mtis.size(); i++)
1397         mtis[i]->invalidateCode();
1398 }
1399
1400 bool baseTrampInstance::linkCode() {
1401     if (isEmpty()) {
1402         linked_ = true;
1403         return true;
1404     }
1405
1406     unsigned cost = 0;
1407     for (unsigned i = 0; i < mtis.size(); i++) {
1408         mtis[i]->linkCode();
1409         cost += mtis[i]->cost();
1410     }
1411
1412     if (!BPatch::bpatch->isMergeTramp()) {
1413       Address leave = trampPreAddr() + baseT->instStartOffset;
1414       
1415       Address arrive = baseT->firstMini->getMTInstanceByBTI(this)->trampBase;
1416         
1417         inst_printf("writing branch from 0x%x to 0x%x, baseT (%p)->miniT (%p)\n",
1418                     leave, arrive,
1419                     this,
1420                     baseT->firstMini->getMTInstanceByBTI(this));
1421         generateAndWriteBranch(baseT->proc(), 
1422                                leave, 
1423                                arrive, 
1424                                instruction::maxJumpSize());
1425     }
1426
1427     // Cost calculation
1428     if (cost) {
1429         // If 0, all mts were set to noCost, so don't increment us.
1430         cost += baseT->getBTCost();
1431     }
1432     updateTrampCost(cost);
1433
1434     linked_ = true;
1435     return true;
1436 }
1437
1438 generatedCodeObject *baseTrampInstance::replaceCode(generatedCodeObject *newParent) {
1439     // Since we are generated in-line, we return a copy
1440     // instead of ourselves.
1441
1442     // Though if we haven't been generated yet, don't bother
1443     inst_printf("replaceCode for baseTramp %p, new par %p, previous %p\n", this,
1444                 newParent, multiT);
1445     multiTramp *newMulti = dynamic_cast<multiTramp *>(newParent);
1446     assert(newMulti);
1447     
1448     if (!generated_) {
1449         multiT = newMulti;
1450         return this;
1451     }
1452     
1453     baseTrampInstance *newBTI = baseT->findOrCreateInstance(newMulti);
1454     assert(newBTI);
1455     for (unsigned i = 0; i < mtis.size(); i++) {
1456         
1457         generatedCodeObject *gen = mtis[i]->replaceCode(newBTI);
1458         miniTrampInstance *newMTI = dynamic_cast<miniTrampInstance *>(gen);
1459         assert(newMTI);
1460     }
1461     newBTI->updateMTInstances();
1462     return newBTI;
1463 }
1464
1465 void baseTrampInstance::deleteMTI(miniTrampInstance *mti) {
1466     for (unsigned i = 0; i < mtis.size(); i++) {
1467         if (mtis[i] == mti) {
1468             mtis[i] = mtis.back();
1469             mtis.pop_back();
1470             return;
1471         }
1472     }
1473     assert(0);
1474     return;
1475 }
1476
1477 Address baseTrampInstance::uninstrumentedAddr() const {
1478     if (fallthrough_)
1479         return fallthrough_->uninstrumentedAddr();
1480     else if (previous_)
1481         return previous_->uninstrumentedAddr();
1482     else 
1483         assert(0);
1484     return 0;
1485 }
1486
1487 bool baseTramp::threaded() const {
1488    if (!proc()->multithread_ready() || suppress_threads_)
1489       return false;
1490    return true;
1491 }
1492
1493 void baseTramp::setThreaded(bool new_val)
1494 {
1495    if (suppress_threads_ != new_val)
1496       return;
1497    if (valid)
1498    {
1499       valid = false;
1500       preTrampCode_.invalidate();
1501       postTrampCode_.invalidate();
1502    }
1503    suppress_threads_ = !new_val;
1504 }
1505
1506 void *baseTrampInstance::getPtrToInstruction(Address /*addr*/ ) const {
1507     assert(0); // FIXME if we do out-of-line baseTramps
1508     return NULL;
1509 }