Here's forge's code in World.class lines 3347 to 3366:
/**
* Counts how many entities of an entity class exist in the world. Args: entityClass
*/
public int countEntities(Class entityType)
{
int i = 0;
Iterator iterator = this.loadedEntityList.iterator();
while (iterator.hasNext())
{
Entity entity = (Entity)iterator.next();
if ((!(entity instanceof EntityLiving) || !((EntityLiving)entity).isNoDespawnRequired()) && entityType.isAssignableFrom(entity.getClass()))
{
++i;
}
}
return i;
}
I can't find what calls this, but ".isNoDespawnRequired()" returns the persistenceRequired value, and this appears to be counting mobs, and those with persistence required are not counted.
However, in SpawnerAnimals.class, findChunksForSpawning() looks like what is doing the spawning for hostiles and animals, and it calls a countEntities function, same name as above, but with a different set of parms, which leads to this function in World.class instead:
/**
* Returns a count of entities that classify themselves as the specified creature type.
*/
public int countEntities(EnumCreatureType type, boolean forSpawnCount)
{
int count = 0;
for (int x = 0; x < loadedEntityList.size(); x++)
{
if (((Entity)loadedEntityList.get(x)).isCreatureType(type, forSpawnCount))
{
count++;
}
}
return count;
}
It appears (from what I can tell) that this is being used to apply the mob cap, and the only thing it considers is if it's a hostile type. If you apply name tags to [mob cap] hostiles or allow [mob cap] zombies to pick up an item, no other hostiles will spawn in that area while you are in Forge 1.8. (If you save the map and load it up in vanilla 1.8, other hostiles still spawn.)