Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mistake #22 "nil vs empty slices" regarding memory allocation of empty slices #74

Closed
denpeshkov opened this issue Dec 22, 2023 · 3 comments
Labels
erratum Erratum

Comments

@denpeshkov
Copy link

denpeshkov commented Dec 22, 2023

Item 22 says:

One of the main differences between a nil and an empty slice regards allocations. Initializing a nil slice doesn’t require any allocation, which isn’t the case for an empty slice.

Correct me if I am wrong, but AFAIK both slices will have no memory allocations.

Slices are represented in memory as 3 words, defined by the slice header:

type slice struct {
	array unsafe.Pointer
	len   int
	cap   int
}

A nil slice is actually a zero value of the slice header:

slice {
	array: nil,
	len:   0,
	cap:   0,
}

An empty slice is just a slice with len and cap equal to 0 and an array pointing to 'zero-sized' array:

slice {
	array: unsafe.Pointer(&zerobase),
	len:   0,
	cap:   0,
}

The value of the array is the address of the runtime.zerobase, the base address for all 0-byte allocations

@denpeshkov denpeshkov added the erratum Erratum label Dec 22, 2023
@wureny
Copy link
Contributor

wureny commented Dec 23, 2023

The empty slice itself doesn't need memory allocation, but when Initializing it, we also need to initialize the slice header, which contains a pointer(array) that needs memory allocations. zerobase is the base address for all 0-byte allocations, but itself is not 0.

@denpeshkov
Copy link
Author

denpeshkov commented Dec 23, 2023

@wureny

I am not really proficient in Assembly, but looking at the code, the only difference is which value gets stored in AX register.

Assembler for nil slice:

XORL	AX, AX // zeroing
XORL	BX, BX // zeroing
MOVQ	BX, CX	

Assembler for empty slice:

LEAQ	runtime.zerobase(SB), AX // take address
XORL	BX, BX // zeroing
MOVQ	BX, CX

Compiled for GOOS=linux GOARCH=AMD64

@teivah
Copy link
Owner

teivah commented Mar 5, 2024

As said in #74 (comment)

@teivah teivah closed this as completed Mar 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
erratum Erratum
Projects
None yet
Development

No branches or pull requests

3 participants