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); } }
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; }
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; }
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(); }
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 --; }
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; }
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_); }