compiler: revert `for package-scope "a = b; b = x" just set "a = x"`
This patch to the Go frontend reverts https://go.dev/cl/245098, which introduced incorrect initialization ordering. This patch adjusts the runtime package to work even with that change reverted. Original description of change 245098: This avoids requiring an init function to initialize the variable. This can only be done if x is a static initializer. The go1.15rc1 runtime package relies on this optimization. The package has a variable "var maxSearchAddr = maxOffAddr". The maxSearchAddr variable is used by code that runs before package initialization is complete. This is for https://golang.org/issue/51913. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline. Ian
5d6db440fd8ec4089fba83760874d70f449037a6 diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 75ee2e3aaca..bcb526c85b9 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -323ab0e6fab89978bdbd83dca9c2ad9c5dcd690f +62fc90f52da2f52cbe3b4f10e560dc6aa59baeb5 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 30d5c9fcb0b..d35c6baf582 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -1612,31 +1612,16 @@ Gogo::write_globals() // The initializer is constant if it is the zero-value of the // variable's type or if the initial value is an immutable value // that is not copied to the heap. - Expression* init = var->init(); - - // If we see "a = b; b = x", and x is a static - // initializer, just set a to x. - while (init != NULL && init->var_expression() != NULL) - { - Named_object* ino = init->var_expression()->named_object(); - if (!ino->is_variable() || ino->package() != NULL) - break; - Expression* ino_init = ino->var_value()->init(); - if (ino->var_value()->has_pre_init() - || ino_init == NULL - || !ino_init->is_static_initializer()) - break; - init = ino_init; - } - - bool is_static_initializer; - if (init == NULL) + bool is_static_initializer = false; + if (var->init() == NULL) is_static_initializer = true; else { Type* var_type = var->type(); - init = Expression::make_cast(var_type, init, var->location()); - is_static_initializer = init->is_static_initializer(); + Expression* init = var->init(); + Expression* init_cast = + Expression::make_cast(var_type, init, var->location()); + is_static_initializer = init_cast->is_static_initializer(); } // Non-constant variable initializations might need to create @@ -1655,15 +1640,7 @@ Gogo::write_globals() } var_init_fn = init_fndecl; } - - Bexpression* var_binit; - if (init == NULL) - var_binit = NULL; - else - { - Translate_context context(this, var_init_fn, NULL, NULL); - var_binit = init->get_backend(&context); - } + Bexpression* var_binit = var->get_init(this, var_init_fn); if (var_binit == NULL) ; diff --git a/libgo/go/runtime/mpagealloc.go b/libgo/go/runtime/mpagealloc.go index 2725e3b7c7b..5e40da45d17 100644 --- a/libgo/go/runtime/mpagealloc.go +++ b/libgo/go/runtime/mpagealloc.go @@ -87,7 +87,9 @@ const ( // // We alias maxOffAddr just to make it clear that this is the maximum address // for the page allocator's search space. See maxOffAddr for details. -var maxSearchAddr = maxOffAddr +func maxSearchAddr() offAddr { + return maxOffAddr +} // Global chunk index. // @@ -331,13 +333,13 @@ func (p *pageAlloc) init(mheapLock *mutex, sysStat *sysMemStat) { p.sysInit() // Start with the searchAddr in a state indicating there's no free memory. - p.searchAddr = maxSearchAddr + p.searchAddr = maxSearchAddr() // Set the mheapLock. p.mheapLock = mheapLock // Initialize scavenge tracking state. - p.scav.scavLWM = maxSearchAddr + p.scav.scavLWM = maxSearchAddr() } // tryChunkOf returns the bitmap data for the given chunk. @@ -760,7 +762,7 @@ nextLevel: } if l == 0 { // We're at level zero, so that means we've exhausted our search. - return 0, maxSearchAddr + return 0, maxSearchAddr() } // We're not at level zero, and we exhausted the level we were looking in. @@ -854,7 +856,7 @@ func (p *pageAlloc) alloc(npages uintptr) (addr uintptr, scav uintptr) { // exhausted. Otherwise, the heap still might have free // space in it, just not enough contiguous space to // accommodate npages. - p.searchAddr = maxSearchAddr + p.searchAddr = maxSearchAddr() } return 0, 0 } diff --git a/libgo/go/runtime/mpagecache.go b/libgo/go/runtime/mpagecache.go index 7206e2dbdb7..5bad4f789a1 100644 --- a/libgo/go/runtime/mpagecache.go +++ b/libgo/go/runtime/mpagecache.go @@ -143,7 +143,7 @@ func (p *pageAlloc) allocToCache() pageCache { if addr == 0 { // We failed to find adequate free space, so mark the searchAddr as OoM // and return an empty pageCache. - p.searchAddr = maxSearchAddr + p.searchAddr = maxSearchAddr() return pageCache{} } ci := chunkIndex(addr)