runtime (gc): correct scan bounds
This fixes 2 bugs in the GC scan bounds: 1. On AVR, the GC could sometimes read one byte past the end of a block due to the difference between pointer size and alignment. 2. On WASM, the linker does not properly align the marker for the end of the globals section. A manual alignment operation has been added to markGlobals to work around this.
Этот коммит содержится в:
		
							родитель
							
								
									62bda8e129
								
							
						
					
					
						коммит
						e6fbad13c6
					
				
					 2 изменённых файлов: 23 добавлений и 1 удалений
				
			
		|  | @ -430,7 +430,17 @@ func markRoots(start, end uintptr) { | |||
| 		if start >= end { | ||||
| 			runtimePanic("gc: unexpected range to mark") | ||||
| 		} | ||||
| 		if start%unsafe.Alignof(start) != 0 { | ||||
| 			runtimePanic("gc: unaligned start pointer") | ||||
| 		} | ||||
| 		if end%unsafe.Alignof(end) != 0 { | ||||
| 			runtimePanic("gc: unaligned end pointer") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Reduce the end bound to avoid reading too far on platforms where pointer alignment is smaller than pointer size. | ||||
| 	// If the size of the range is 0, then end will be slightly below start after this. | ||||
| 	end -= unsafe.Sizeof(end) - unsafe.Alignof(end) | ||||
| 
 | ||||
| 	for addr := start; addr < end; addr += unsafe.Alignof(addr) { | ||||
| 		root := *(*uintptr)(unsafe.Pointer(addr)) | ||||
|  |  | |||
|  | @ -1,12 +1,24 @@ | |||
| //go:build (gc.conservative || gc.extalloc) && (baremetal || tinygo.wasm) | ||||
| // +build gc.conservative gc.extalloc | ||||
| // +build baremetal tinygo.wasm | ||||
| 
 | ||||
| package runtime | ||||
| 
 | ||||
| import "unsafe" | ||||
| 
 | ||||
| // markGlobals marks all globals, which are reachable by definition. | ||||
| // | ||||
| // This implementation marks all globals conservatively and assumes it can use | ||||
| // linker-defined symbols for the start and end of the .data section. | ||||
| func markGlobals() { | ||||
| 	markRoots(globalsStart, globalsEnd) | ||||
| 	end := globalsEnd | ||||
| 	if GOARCH == "wasm" { | ||||
| 		// This is a workaround for a bug in wasm-ld: wasm-ld doesn't always | ||||
| 		// align __heap_base and when this memory is shared through an API, it | ||||
| 		// might result in unaligned memory. For details, see: | ||||
| 		// https://reviews.llvm.org/D106499 | ||||
| 		// It should be removed once we switch to LLVM 13, where this is fixed. | ||||
| 		end = end &^ (unsafe.Alignof(end) - 1) | ||||
| 	} | ||||
| 	markRoots(globalsStart, end) | ||||
| } | ||||
|  |  | |||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Nia Waldvogel
						Nia Waldvogel