void Object::CalculateSizeAndPointers() const { TADDR mt = GetMT(); MethodTableInfo* info = g_special_mtCache.Lookup((DWORD_PTR)mt); if (!info->IsInitialized()) { // this is the first time we see this method table, so we need to get the information // from the target FillMTData(); info->BaseSize = mMTData->BaseSize; info->ComponentSize = mMTData->ComponentSize; info->bContainsPointers = mMTData->bContainsPointers; // The following request doesn't work on older runtimes. For those, the // objects would just look like non-collectible, which is acceptable. DacpMethodTableCollectibleData mtcd; if (SUCCEEDED(mtcd.Request(g_sos, GetMT()))) { info->bCollectible = mtcd.bCollectible; info->LoaderAllocatorObjectHandle = TO_TADDR(mtcd.LoaderAllocatorObjectHandle); } } if (mSize == (size_t)~0) { mSize = info->BaseSize; if (info->ComponentSize) { // this is an array, so the size has to include the size of the components. We read the number // of components from the target and multiply by the component size to get the size. mSize += info->ComponentSize * GetNumComponents(GetAddress()); } // On x64 we do an optimization to save 4 bytes in almost every string we create. #ifdef _WIN64 // Pad to min object size if necessary if (mSize < min_obj_size) mSize = min_obj_size; #endif // _WIN64 } mPointers = info->bContainsPointers != FALSE; }
void Attribute::Copy(Attribute* dst, Attribute* src, component_index bridge) { euint numComps0 = GetNumComponents(dst); euint numComps1 = GetNumComponents(src); euint numComps2 = bridge.num_comps; euint numComps = numComps0; if (numComps1 < numComps) numComps = numComps1; if (numComps2 < numComps) numComps = numComps2; switch (numComps) { case 1: { FloatAttr* ftDst = dst->DynamicCast<FloatAttr>(); FloatAttr* ftSrc = src->DynamicCast<FloatAttr>(); component comp = ComponentFormat(bridge.comps[0]); if (comp < CompY) ftDst->x = ftSrc->x; } break; case 2: { Float2Attr* ft2Dst = dst->DynamicCast<Float2Attr>(); Float2Attr* ft2Src = src->DynamicCast<Float2Attr>(); component comp = ComponentFormat(bridge.comps[0]); switch (comp) { case CompX: ft2Dst->x = ft2Src->x; break; case CompY: ft2Dst->x = ft2Src->y; break; default: break; } comp = ComponentFormat(bridge.comps[1]); switch (comp) { case CompX: ft2Dst->y = ft2Src->x; break; case CompY: ft2Dst->y = ft2Src->y; break; default: break; } } break; case 3: { Float3Attr* ft3Dst = dst->DynamicCast<Float3Attr>(); Float3Attr* ft3Src = src->DynamicCast<Float3Attr>(); component comp = ComponentFormat(bridge.comps[0]); switch (comp) { case CompX: ft3Dst->x = ft3Src->x; break; case CompY: ft3Dst->x = ft3Src->y; break; case CompZ: ft3Dst->x = ft3Src->z; break; default: break; } comp = ComponentFormat(bridge.comps[1]); switch (comp) { case CompX: ft3Dst->y = ft3Src->x; break; case CompY: ft3Dst->y = ft3Src->y; break; case CompZ: ft3Dst->y = ft3Src->z; break; default: break; } comp = ComponentFormat(bridge.comps[2]); switch (comp) { case CompX: ft3Dst->z = ft3Src->x; break; case CompY: ft3Dst->z = ft3Src->y; break; case CompZ: ft3Dst->z = ft3Src->z; break; default: break; } } break; case 4: { Float4Attr* ft4Dst = dst->DynamicCast<Float4Attr>(); Float4Attr* ft4Src = src->DynamicCast<Float4Attr>(); component comp = ComponentFormat(bridge.comps[0]); switch (comp) { case CompX: ft4Dst->x = ft4Src->x; break; case CompY: ft4Dst->x = ft4Src->y; break; case CompZ: ft4Dst->x = ft4Src->z; break; case CompW: ft4Dst->x = ft4Src->w; break; } comp = ComponentFormat(bridge.comps[1]); switch (comp) { case CompX: ft4Dst->y = ft4Src->x; break; case CompY: ft4Dst->y = ft4Src->y; break; case CompZ: ft4Dst->y = ft4Src->z; break; case CompW: ft4Dst->y = ft4Src->w; break; } comp = ComponentFormat(bridge.comps[2]); switch (comp) { case CompX: ft4Dst->z = ft4Src->x; break; case CompY: ft4Dst->z = ft4Src->y; break; case CompZ: ft4Dst->z = ft4Src->z; break; case CompW: ft4Dst->z = ft4Src->w; break; } comp = ComponentFormat(bridge.comps[3]); switch (comp) { case CompX: ft4Dst->w = ft4Src->x; break; case CompY: ft4Dst->w = ft4Src->y; break; case CompZ: ft4Dst->w = ft4Src->z; break; case CompW: ft4Dst->w = ft4Src->w; break; } } break; default: break; } }