示例#1
0
文件: sic.cpp 项目: AdamSpitz/self
  void SICompiler::initTopScope() {
    recompileeScope =
      recompilee ? (RScope*)constructRScopes(recompilee) 
                 : (RScope*)new RNullScope(NULL);
    if (PrintPICScopes) recompileeScope->printTree(0, 0);

    nodeGen->haveStackFrame = true;
    MethodKind kind = method()->kind();
    countID = Memory->code->nextNMethodID();
    SCodeScope* s;
    SScope* parentScope = NULL;
    
    if (L->receiverMap()->is_block()) {
      blockOop block = (blockOop) L->receiver;
      assert_block(block, "expecting a block literal");
      // caution: parentFrame could be on conversion stack, so use
      // sending frame as a starting point
      // I think this hint is bogus--dmu (see NIC)
      frame* sender =
        L->sendingVFrame
          ? L->sendingVFrame->fr
          : currentProcess->last_self_frame(false);
      parentVFrame = block->parentVFrame(sender, true)->as_compiled();
      if (parentVFrame) parentScope = new_SVFrameScope(parentVFrame);
    }

    MethodLookupKey* k= new_MethodLookupKey(L->key);
    SendInfo* info = new SendInfo(k);
    
    switch (kind) {
     case OuterMethodType:
      s = new SMethodScope(method(), methodHolder_or_map(),
                           NULL, recompileeScope, info);
      break;
     case BlockMethodType:
      // taken from NIC by dmu 7/1
      assert(L->receiverMap()->is_block(), "was expecting block");
      if (parentScope) {
        s = new SBlockScope(method(), parentScope, 
                            NULL, recompileeScope, info);
      } else {
        s = new SDeadBlockScope(method(), info);
      }
      break;
     default:
      fatal("unexpected byte code kind");
    }
    
    needRegWindowFlushes = false;
    topScope = s;
    s->vscope = vscopes ? vscopes->top() : NULL;
  }
示例#2
0
  SSelfScope* SCodeScope::tryLookup(SendInfo* info, SExpr* rcvr) {
    // info->rcvr is the overall receiver (e.g. a merge expr), rcvr is
    // a particular branch
    // nmln* depsTop = theSIC->L->deps->top;
    assert(rcvr->hasMap(), "should have a map");
    
    SICLookup* L = new SICLookup(info->l,
                                 rcvr->isConstantSExpr()
                                   ? rcvr->asConstantSExpr()->constant()
                                   : rcvr->map()->enclosing_mapOop(),
                                 info->sel,
                                 info->del,
                                 theSIC->L->deps,
                                 this );

    L->perform_lookup();
    info->key= new_MethodLookupKey(L->key);
    
    if (L->result() == NULL) {
      // nothing found statically
      // should remove unused deps here
      if (L->status == foundNone) {
        // next recompilation might get it via PICs
        theSIC->registerUninlinable(info, NormalFnLimit, 0);
      } else {
        info->uninlinable = true;
      }
      char msg[80];
      sprintf(msg, "lookup failed: %s", lookupStatusString(L->status));
      return notify(info->sel, msg);
    }

    slotDesc* s = L->result()->as_real()->desc;
    assert(! s->is_vm_slot(), "shouldn't be a vm slot");
    RScope* rs = rscope->subScope(_bci, L);
#   if GENERATE_DEBUGGING_AIDS
    if (CheckAssertions) {
      bool isNullRScope = rs->isNullScope(); // for breakpoints
    }
#   endif
    
    if (s->is_map_slot()) {
      // handle constant slots first
      
      if ( !s->data->has_code()) {
        // inline value of a constant slot
        msgCost = 0;
        return new SConstantSlotAccessScope(L, this, rs, rcvr, info);
      } 
      switch ( s->data->kind() ) {
       case BlockMethodType:
        return tryLookupOfBlockMethod(info, rcvr, rs, s->data, L);

       case OuterMethodType:
        return tryLookupOfOuterMethod(info, rcvr, rs, s->data, L);

       default:
         fatal("unexpected kind of code in slot");
      }
    } 

    assert(s->is_obj_slot(), "unexpected slot type");
    // is not map slot
    // found a slot in the receiver or one of its ancestors
    msgCost = 0;

    return
     info->sel->is_1arg_keyword()
       ?  // inline assignment to an instance variable
          (SSelfScope*) new SDataSlotAssignScope(L, this, rs, rcvr, exprStack->top(),
                                   info) 
       :  // inline access of an instance variable
          (SSelfScope*) new SDataSlotAccessScope(L, this, rs, rcvr, info);
  }