Repository: JuliaLang/julia
File: base/summarysize.jl (Julia)

Code before:
    haskey(ss.seen, key) ? (return 0) : (ss.seen[key] = true)
    return (ss.count ? 1 : (Core.sizeof(Int) + Core.sizeof(obj)))
end

function (ss::SummarySize)(obj::DataType)
    key = pointer_from_objref(obj)
    haskey(ss.seen, key) ? (return 0) : (ss.seen[key] = true)
    size::Int = (ss.count ? 1 : (7 * Core.sizeof(Int) + 6 * Core.sizeof(Int32)))
    size += (ss.count ? 1 : (4 * nfields(obj) + ifelse(Sys.WORD_SIZE == 64, 4, 0)))
    size += ss(obj.parameters)::Int
    if isdefined(obj, :types)
        size += ss(obj.types)::Int
    end
    return size
end

function (ss::SummarySize)(obj::Core.TypeName)
    key = pointer_from_objref(obj)
    haskey(ss.seen, key) ? (return 0) : (ss.seen[key] = true)
    return (ss.count ? 1 : Core.sizeof(obj))
end

function (ss::SummarySize)(obj::GenericMemory)
    haskey(ss.seen, obj) ? (return 0) : (ss.seen[obj] = true)
    headersize = 2 * sizeof(Int)
    size::Int = (ss.count ? 1 : headersize)
    datakey = Base.unsafe_convert(Ptr{Cvoid}, obj)
    if !haskey(ss.seen, datakey)
        ss.seen[datakey] = true
        size += (ss.count ? 1 : sizeof(obj))
        T = eltype(obj)
        if !isempty(obj) && T !== Symbol && (!Base.allocatedinline(T) || (T isa DataType && !Base.datatype_pointerfree(T)))
            push!(ss.frontier_x, obj)
            push!(ss.frontier_i, 1)
        end
    end
    return size
end

function (ss::SummarySize)(obj::Core.SimpleVector)
    key = pointer_from_objref(obj)
    haskey(ss.seen, key) ? (return 0) : (ss.seen[key] = true)
    size::Int = (ss.count ? 1 : Core.sizeof(obj))
    if !isempty(obj)
        push!(ss.frontier_x, obj)
        push!(ss.frontier_i, 1)
    end
    return size
end

function (ss::SummarySize)(obj::Module)

Review comment (suggestion):
@oscardssmith Is the header here separate from the `obj` itself that we count below? I don't quite grok the accounting

Code after:
    key = ccall(:jl_value_ptr, Ptr{Cvoid}, (Any,), obj)
    haskey(ss.seen, key) ? (return 0) : (ss.seen[key] = true)
    return (ss.count ? 1 : (Core.sizeof(Int) + Core.sizeof(obj)))
end

function (ss::SummarySize)(obj::DataType)
    key = pointer_from_objref(obj)
    haskey(ss.seen, key) ? (return 0) : (ss.seen[key] = true)
    size::Int = ss.count ? 1 : sizeof(DataType)
    size += ss(obj.parameters)::Int
    if isdefined(obj, :types)
        size += ss(obj.types)::Int
    end
    return size
end

function (ss::SummarySize)(obj::Core.TypeName)
    key = pointer_from_objref(obj)
    haskey(ss.seen, key) ? (return 0) : (ss.seen[key] = true)
    return (ss.count ? 1 : Core.sizeof(obj))
end

function (ss::SummarySize)(obj::GenericMemory)
    haskey(ss.seen, obj) ? (return 0) : (ss.seen[obj] = true)
    headersize = 2 * sizeof(Int)
    size::Int = (ss.count ? 1 : headersize)
    datakey = unsafe_convert(Ptr{Cvoid}, obj)
    if !haskey(ss.seen, datakey)
        ss.seen[datakey] = true
        if !ss.count
            size += sizeof(obj)
        elseif pointer_from_objref(obj) + 16 != datakey
            size += 1
        end
        T = eltype(obj)
        if !isempty(obj) && T !== Symbol && (!allocatedinline(T) || (T isa DataType && !datatype_pointerfree(T)))
            push!(ss.frontier_x, obj)
            push!(ss.frontier_i, 1)
        end
    end
    return size
end

function (ss::SummarySize)(obj::Core.SimpleVector)
    key = pointer_from_objref(obj)
    haskey(ss.seen, key) ? (return 0) : (ss.seen[key] = true)
    size::Int = (ss.count ? 1 : Core.sizeof(obj))
    if !isempty(obj)
        push!(ss.frontier_x, obj)
        push!(ss.frontier_i, 1)
    end