Beispiel #1
0
void nmethod::makeZombie(bool unlnk) {
  // mark this nmethod as zombie (it is almost dead and can be flushed as
  // soon as it is no longer on the stack)
  if (!isZombie()) {
    flags.isZombie = 1;
    flags.isToBeRecompiled = 0;
    if (unlnk) unlink();
    else       removeFromCodeTable(); // added by dmu 1/03; see comment in nmethod::flush
    zoneLink.remove();
    Memory->code->zombies.add(&zoneLink);
  }
}
Beispiel #2
0
void CPlayer::setPlayer(int connfd,
                        const char* username,
                        const char* password,
                        const CChips& chips,
                        u_int32_t ipaddress)
{
    strncpy(username_, username, PDUSTRINGSIZE);
    strncpy(password_, password, PDUSTRINGSIZE);
    memset(city_, 0, sizeof(city_));

    if (chips == 0 || isZombie())
    {   // zombie or tournament free seat =>
        // this seat/player already has chips assigned
    }
    else
    {
        chips_ = chips;
    }

    // XXX Does not work - in normal tournament logins
    // the socket must be set immediately!
    // XXX Zombie: when player reanimates zombie,
    // new socket is saved to temporary variable.
    // Cplm::rebuildRing will then take the new
    // socket into use. 
    connfd_ = connfd;

    if (state_ == PLAYER_STATE_UNUSED)
        state_ = PLAYER_STATE_LOGGEDIN; 
    disconnected_ = false;
    sitouts_ = 0;
    pings_ = 0;
    sendError_ = false;
    ipaddr_ = ipaddress;
    if (ipaddr_ != 0)
        RegisterIPAddress(ipaddr_);

    // XXX Fix tournament double big blind bug
    if (!CTournament::Inst()->isTournament())
        missedBlind_ = 0;

    isFirstHand_ = true;
}
Beispiel #3
0
bool nmethod::mustNotRecompile() {
  // answers true if nm must not be recompiled (for non-performance-related
  // reasons)

  // never recompile new-compiled uncommon branches
  // don't recompile zombies (if they're zombies because of uncommon branch
  // traps, the recompiled nmethod already exists)
  if (isZombie() || isInvalid()) return true;

# ifdef SIC_COMPILER
  // the SIC doesn't compile access methods
  if (isAccess()) return true;
  if (version() >= MaxVersions && !isUncommonRecompiled())
    return true;
# endif

  // don't recompile VM-generated lookup error methods (breaks too many
  // assertions because method oop can change (new method generated during
  // lookup)
  methodMap* mm = (methodMap*)method()->map();
  return mm->file()->length() == 7
     &&  strncmp(mm->file()->bytes(), "<error>", 7) == 0;
}
Beispiel #4
0
void nmethod::flush() {
  BlockProfilerTicks bpt(exclude_nmethod_flush);
  CSect cs(profilerSemaphore);          // for profiler
# if GENERATE_DEBUGGING_AIDS
    if (CheckAssertions) {
      // for debugging
      if (nmethodFlushCount  &&  --nmethodFlushCount == 0)
        warning("nmethodFlushCount");
      if (this == (nmethod*)catchThisOne) warning("caught nmethod");
    }
# endif
  
  // EventMarker em("flushing nmethod %#lx %s", this, "");
  if (PrintMethodFlushing) {
    ResourceMark m;
    char *compilerName = VMString[compiler()]->copy_null_terminated();
    lprintf("*flushing %s%s%s-nmethod 0x%lx %d\t(",
           isZombie() ? "zombie " : "", 
           isAccess() ? "access " : "",
           compilerName, (void*)(long unsigned)this, (void*)useCount[id]);
    printName(0, key.selector);
    lprintf(")");
  }

  // always check the following - tests are really cheap
  if (flags.flushed) fatal1("nmethod %#lx already flushed", this);
  if (zone::frame_chain_nesting == 0) fatal("frames must be chained when flushing");

  if (frame_chain != NoFrameChain) {
    // Can't remove an nmethod from deps chains now, because later
    // programming changes may need to invalidate it.
    // That is, don't unlink() now.
   
    // See comment for makeZombie routine. The comment above is the 
    // "original comment" referred to there.
    // -- dmu 1/12/03

    if (this == recompilee) {
      // nmethod is being recompiled; cannot really flush yet
      // em.event.args[1] = "(being recompiled)";
      if (PrintMethodFlushing) {
        lprintf(" (being recompiled)\n");
      }
    } else {
      // nmethod is currently being executed; cannot flush yet
      // em.event.args[1] = "(currently active)";
      if (PrintMethodFlushing) {
        lprintf(" (currently active)\n");
      }
    }
    makeZombie(false);
  } else {
    unlink();
  
    // nmethod is not being executed; completely throw away
    // em.event.args[1] = "(not currently active)";
    if (PrintMethodFlushing) {
      lprintf("\n");
    }
    flatProfiler->flush((char*)this, instsEnd());
    zoneLink.remove();
    rememberLink.remove();
    for (addrDesc* p = locs(), *pend = locsEnd(); p < pend; p++) {
      if (p->isSendDesc()) {
        p->asSendDesc(this)->unlink();
      } else if (p->isDIDesc()) {
        p->asDIDesc(this)->dependency()->flush();
      }
    }
    flags.flushed = 1;                        // to detect flushing errors
#   if GENERATE_DEBUGGING_AIDS
    if (CheckAssertions) {
      set_oops((oop*)insts(), instsLen()/oopSize, 0); // for quicker detection
    }
#   endif
    Memory->code->free_nmethod(this);
  }
  MachineCache::flush_instruction_cache_for_debugging();
}
Beispiel #5
0
void nmethod::print() {
  ResourceMark rm;
  printIndent();
  lprintf("(nmethod*)%#lx", this);
  if (scopes->root()->isDataAccessScope()) {
    lprintf(" (data access)");
  } else if (scopes->root()->isDataAssignmentScope()) {
    lprintf(" (data assignment)");
  } else {
    lprintf(" for method %#lx", method());
  }
  lprintf(" { ");
  if (isYoung()) lprintf("YOUNG ");
  switch (compiler()) {
   case NIC: lprintf("NIC "); if (isImpureNIC()) lprintf("impure "); break;
   case SIC: lprintf("SIC level %ld ", level()); break;
   default:  lprintf("!?!unknown compiler!?! "); break;
  }
  if (version())           lprintf("v%d ", version());
  if (isDI())              lprintf("DI ");
  if (isZombie())          lprintf("zombie ");
  if (isInvalid())         lprintf("INVALID ");
  if (isDebug())           lprintf("DEBUG ");
  if (isToBeRecompiled())  lprintf("TBR ");
  if (isUncommon() || isUncommonRecompiled()) lprintf("UNCOMMON ");
  lprintf("}:\n");
 
  lprintf( "incoming_arg_count = %d\n", incoming_arg_count() );
  
  print_platform_specific_data();
  
  Indent ++;
  
  key.print();
  
  printIndent();
  lprintf("code table link: %#lx\n", codeTableLink);
  
  printIndent();
  lprintf("remember link: ");
  rememberLink.print();
  lprintf("\n");
  
  printIndent();
  lprintf("linked sends: ");
  linkedSends.print();
  lprintf("\n");
  
  printIndent();
  lprintf("di link: ");
  diLink.print();
  lprintf("\n");
  
  printIndent();
  lprintf("instructions (%ld bytes): %#lx,%#lx/i / x/%ldi %#lx\n",
         instsLen(), 
         insts(),
         instsEnd() - oopSize,
         instsLen() / oopSize,
         insts());
  printIndent(); lprintf("p ((nmethod*)%#lx)->printCode() \n", this);
  scopes->print();
  // printLocs();
  // printDeps();
  Indent --;
}
Beispiel #6
0
static really_inline
char roseCatchUpLeftfix(const struct RoseEngine *t, char *state,
                        struct hs_scratch *scratch, u32 qi,
                        const struct LeftNfaInfo *left) {
    assert(!left->transient); // active roses only

    struct core_info *ci = &scratch->core_info;
    const u32 qCount = t->queueCount;
    struct mq *q = scratch->queues + qi;
    const struct NFA *nfa = getNfaByQueue(t, qi);

    if (nfaSupportsZombie(nfa)
        && ci->buf_offset /* prefix can be alive with no q */
        && !fatbit_isset(scratch->aqa, qCount, qi)
        && isZombie(t, state, left)) {
        DEBUG_PRINTF("yawn - zombie\n");
        return 1;
    }

    if (left->stopTable) {
        enum MiracleAction mrv =
            roseScanForMiracles(t, state, scratch, qi, left, nfa);
        switch (mrv) {
        case MIRACLE_DEAD:
            return 0;
        case MIRACLE_SAVED:
            return 1;
        default:
            assert(mrv == MIRACLE_CONTINUE);
            break;
        }
    }

    if (!fatbit_set(scratch->aqa, qCount, qi)) {
        initRoseQueue(t, qi, left, scratch);

        s32 sp;
        if (ci->buf_offset) {
            sp = -(s32)loadRoseDelay(t, state, left);
        } else {
            sp = 0;
        }

        DEBUG_PRINTF("ci->len=%zu, sp=%d, historyRequired=%u\n", ci->len, sp,
                     t->historyRequired);

        if ( ci->len - sp + 1 < t->historyRequired) {
            // we'll end up safely in the history region.
            DEBUG_PRINTF("safely in history, skipping\n");
            storeRoseDelay(t, state, left, (s64a)ci->len - sp);
            return 1;
        }

        pushQueueAt(q, 0, MQE_START, sp);
        if (left->infix || ci->buf_offset + sp > 0) {
            loadStreamState(nfa, q, sp);
        } else {
            pushQueueAt(q, 1, MQE_TOP, sp);
            nfaQueueInitState(nfa, q);
        }
    } else {
        DEBUG_PRINTF("queue already active\n");
        if (q->end - q->cur == 1 && q_cur_type(q) == MQE_START) {
            DEBUG_PRINTF("empty queue, start loc=%lld\n", q_cur_loc(q));
            s64a last_loc = q_cur_loc(q);
            if (ci->len - last_loc + 1 < t->historyRequired) {
                // we'll end up safely in the history region.
                DEBUG_PRINTF("safely in history, saving state and skipping\n");
                saveStreamState(nfa, q, last_loc);
                storeRoseDelay(t, state, left, (s64a)ci->len - last_loc);
                return 1;
            }
        }
    }

    // Determine whether the byte before last_loc will be in the history
    // buffer on the next stream write.
    s64a last_loc = q_last_loc(q);
    s64a leftovers = ci->len - last_loc;
    if (leftovers + 1 >= t->historyRequired) {
        u32 catchup_offset = left->maxLag ? left->maxLag - 1 : 0;
        last_loc = (s64a)ci->len - catchup_offset;
    }

    if (left->infix) {
        if (infixTooOld(q, last_loc)) {
            DEBUG_PRINTF("infix died of old age\n");
            return 0;
        }
        reduceInfixQueue(q, last_loc, left->maxQueueLen, q->nfa->maxWidth);
    }

    DEBUG_PRINTF("end scan at %lld\n", last_loc);
    pushQueueNoMerge(q, MQE_END, last_loc);

#ifdef DEBUG
    debugQueue(q);
#endif

    char rv = nfaQueueExecRose(nfa, q, MO_INVALID_IDX);
    if (!rv) { /* nfa is dead */
        DEBUG_PRINTF("died catching up to stream boundary\n");
        return 0;
    } else {
        DEBUG_PRINTF("alive, saving stream state\n");
        if (nfaSupportsZombie(nfa) &&
            nfaGetZombieStatus(nfa, q, last_loc) == NFA_ZOMBIE_ALWAYS_YES) {
            DEBUG_PRINTF("not so fast - zombie\n");
            setAsZombie(t, state, left);
        } else {
            saveStreamState(nfa, q, last_loc);
            storeRoseDelay(t, state, left, (s64a)ci->len - last_loc);
        }
    }

    return 1;
}
Beispiel #7
0
void Mouth::onCollision(PhysicsBody* pOther, float impulseMagnitude) {
	if (impulseMagnitude > 1000) {
//TODO implement hurt
		return;
	}
	b2AABB otherAABB;
	pOther->b2Body_->GetFixtureList()[0].GetShape()->ComputeAABB(
			&otherAABB,
			pOther->b2Body_->GetTransform(),
			0);
	b2Vec2 otherSize = 2.f * otherAABB.GetExtents();
	float maxSwallowRatio = min(1.f, width_ / max(max(width_, otherSize.x), otherSize.y));
	float maxFoodAvailable = 0;

	// check how much food there is:
	switch (pOther->userObjectType_) {
	case ObjectTypes::FOOD_CHUNK: {
		auto pFoodChunk = static_cast<FoodChunk*>(pOther->userPointer_);
		if (pFoodChunk->isZombie())
			return;
		maxFoodAvailable = pFoodChunk->getMassLeft();
		break;
	}
	case ObjectTypes::BPART_BONE:
	case ObjectTypes::BPART_EGGLAYER:
	case ObjectTypes::BPART_GRIPPER:
	case ObjectTypes::BPART_MOUTH:
	case ObjectTypes::BPART_TORSO:
		maxFoodAvailable = static_cast<BodyPart*>(pOther->userPointer_)->getFoodValue();
		break;
	case ObjectTypes::BPART_ZYGOTE:
		ERROR("Implement zygote eating - must check it's not owner - or have smell or something");
		break;
	default:
		ERROR("Mouth can't handle object type "<<(int)pOther->userObjectType_)
	};

	// compute food amount that will be transfered:
	float maxSwallow = min(maxFoodAvailable, maxSwallowRatio * maxFoodAvailable); // how much mass could we swallow if buffer allowed it?
	float bufferAvail = bufferSize_ - usedBuffer_;
	float actualFoodAmountTransferred = min(bufferAvail, maxSwallow);
	usedBuffer_ += actualFoodAmountTransferred;

	// LOGLN("eat " << (int)pOther->userObjectType_ << " in amount: " << actualFoodAmountTransferred);

	// consume the food:
	switch (pOther->userObjectType_) {
	case ObjectTypes::FOOD_CHUNK: {
		static_cast<FoodChunk*>(pOther->userPointer_)->consume(actualFoodAmountTransferred);
		break;
	case ObjectTypes::BPART_BONE:
	case ObjectTypes::BPART_EGGLAYER:
	case ObjectTypes::BPART_GRIPPER:
	case ObjectTypes::BPART_MOUTH:
	case ObjectTypes::BPART_TORSO:
		static_cast<BodyPart*>(pOther->userPointer_)->consumeFoodValue(actualFoodAmountTransferred);
		break;
	}
	default:
		ERROR("Mouth can't handle object type "<<(int)pOther->userObjectType_)
	};
}

void Mouth::update(float dt) {
	PERF_MARKER_FUNC;
	if (isDead())
		return;
	if (usedBuffer_ > 0)
		usedBuffer_ -= parent_->addFood(usedBuffer_);
}