/* mps_addr_fmt -- what format might this address have? * * .per-pool: There's no reason why all objects in a pool should have * the same format. But currently, MPS internals support at most one * format per pool. * * If the address is in a pool and has a format, returns TRUE and * updates *mps_fmt_o to be that format. Otherwise, returns FALSE * and does not update *mps_fmt_o. * * Note: may return an MPS-internal format. */ mps_bool_t mps_addr_fmt(mps_fmt_t *mps_fmt_o, mps_arena_t arena, mps_addr_t p) { Bool b; Pool pool; Format format = 0; AVER(mps_fmt_o != NULL); /* mps_arena -- will be checked by ArenaEnterRecursive */ /* p -- cannot be checked */ /* One of the few functions that can be called during the call to an MPS function. IE this function can be called when walking the heap. */ ArenaEnterRecursive(arena); /* .per-pool */ b = PoolOfAddr(&pool, arena, (Addr)p); if(b) b = PoolFormat(&format, pool); ArenaLeaveRecursive(arena); if(b) *mps_fmt_o = (mps_fmt_t)format; return b; }
Bool BufferTrip(Buffer buffer, Addr p, Size size) { Pool pool; AVERT(Buffer, buffer); AVER(p != 0); AVER(size > 0); AVER(SizeIsAligned(size, buffer->alignment)); /* The limit field should be zero, because that's how trip gets */ /* called. See .commit.trip. */ AVER(buffer->ap_s.limit == 0); /* Of course we should be trapped. */ AVER(BufferIsTrapped(buffer)); /* The init and alloc fields should be equal at this point, because */ /* the step .commit.update has happened. */ AVER(buffer->ap_s.init == buffer->ap_s.alloc); /* The p parameter points at the base address of the allocated */ /* block, the end of which should now coincide with the init and */ /* alloc fields. */ /* Note that we don't _really_ care about p too much. We don't */ /* do anything else with it apart from these checks. (in particular */ /* it seems like the algorithms could be modified to cope with the */ /* case of the object having been copied between Commit updating i */ /* and testing limit) */ AVER(AddrAdd(p, size) == buffer->ap_s.init); pool = BufferPool(buffer); AVER(PoolHasAddr(pool, p)); /* .trip.unflip: If the flip occurred before commit set "init" */ /* to "alloc" (see .commit.before) then the object is invalid */ /* (won't've been scanned) so undo the allocation and fail commit. */ /* Otherwise (see .commit.after) the object is valid (will've been */ /* scanned) so commit can simply succeed. */ if ((buffer->mode & BufferModeFLIPPED) && buffer->ap_s.init != buffer->initAtFlip) { /* Reset just enough state for Reserve/Fill to work. */ /* The buffer is left trapped and we leave the untrapping */ /* for the next reserve (which goes out of line to Fill */ /* (.fill.unflip) because the buffer is still trapped) */ buffer->ap_s.init = p; buffer->ap_s.alloc = p; return FALSE; } /* Emit event including class if logged */ if (buffer->mode & BufferModeLOGGED) { Bool b; Format format; Addr clientClass; b = PoolFormat(&format, buffer->pool); if (b) { clientClass = format->klass(p); } else { clientClass = (Addr)0; } EVENT4(BufferCommit, buffer, p, size, clientClass); } return TRUE; }