diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-10-28 22:34:47 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-10-28 22:34:47 +0000 |
commit | 94f56408db96e2e12f6e1322ed2c1c465df934f6 (patch) | |
tree | f5eaac76bc47cc2637e5e30b9ff6c27499fac2d9 /libgo/runtime | |
parent | 21f1031d6cc228e2b468338b3dfa4303d54ac207 (diff) | |
download | gcc-94f56408db96e2e12f6e1322ed2c1c465df934f6.zip gcc-94f56408db96e2e12f6e1322ed2c1c465df934f6.tar.gz gcc-94f56408db96e2e12f6e1322ed2c1c465df934f6.tar.bz2 |
compiler, runtime: copy slice code from Go 1.7 runtime
Change the compiler handle append as the gc compiler does: call a
function to grow the slice, but otherwise assign the new elements
directly to the final slice.
For the current gccgo memory allocator the slice code has to call
runtime_newarray, not mallocgc directly, so that the allocator sets the
TypeInfo_Array bit in the type pointer.
Rename the static function cnew to runtime_docnew, so that the stack
trace ignores it when ignoring runtime functions. This was needed to
fix the runtime/pprof tests on 386.
Reviewed-on: https://go-review.googlesource.com/32218
From-SVN: r241667
Diffstat (limited to 'libgo/runtime')
-rw-r--r-- | libgo/runtime/go-append.c | 74 | ||||
-rw-r--r-- | libgo/runtime/go-copy.c | 22 | ||||
-rw-r--r-- | libgo/runtime/go-make-slice.c | 99 | ||||
-rw-r--r-- | libgo/runtime/malloc.goc | 8 | ||||
-rw-r--r-- | libgo/runtime/runtime.h | 3 |
5 files changed, 6 insertions, 200 deletions
diff --git a/libgo/runtime/go-append.c b/libgo/runtime/go-append.c deleted file mode 100644 index 1b2d49e..0000000 --- a/libgo/runtime/go-append.c +++ /dev/null @@ -1,74 +0,0 @@ -/* go-append.c -- the go builtin append function. - - Copyright 2010 The Go Authors. All rights reserved. - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. */ - -#include "runtime.h" -#include "go-panic.h" -#include "go-type.h" -#include "array.h" -#include "arch.h" -#include "malloc.h" - -/* We should be OK if we don't split the stack here, since the only - libc functions we call are memcpy and memmove. If we don't do - this, we will always split the stack, because of memcpy and - memmove. */ -extern struct __go_open_array -__go_append (struct __go_open_array, void *, uintptr_t, uintptr_t) - __attribute__ ((no_split_stack)); - -struct __go_open_array -__go_append (struct __go_open_array a, void *bvalues, uintptr_t bcount, - uintptr_t element_size) -{ - uintptr_t ucount; - intgo count; - - if (bvalues == NULL || bcount == 0) - return a; - - ucount = (uintptr_t) a.__count + bcount; - count = (intgo) ucount; - if ((uintptr_t) count != ucount || count <= a.__count) - runtime_panicstring ("append: slice overflow"); - - if (count > a.__capacity) - { - intgo m; - uintptr capmem; - void *n; - - m = a.__capacity; - if (m + m < count) - m = count; - else - { - do - { - if (a.__count < 1024) - m += m; - else - m += m / 4; - } - while (m < count); - } - - if (element_size > 0 && (uintptr) m > MaxMem / element_size) - runtime_panicstring ("growslice: cap out of range"); - - capmem = runtime_roundupsize (m * element_size); - - n = __go_alloc (capmem); - __builtin_memcpy (n, a.__values, a.__count * element_size); - - a.__values = n; - a.__capacity = m; - } - - __builtin_memmove ((char *) a.__values + a.__count * element_size, - bvalues, bcount * element_size); - a.__count = count; - return a; -} diff --git a/libgo/runtime/go-copy.c b/libgo/runtime/go-copy.c deleted file mode 100644 index 05e16acb..0000000 --- a/libgo/runtime/go-copy.c +++ /dev/null @@ -1,22 +0,0 @@ -/* go-append.c -- the go builtin copy function. - - Copyright 2010 The Go Authors. All rights reserved. - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. */ - -#include <stddef.h> -#include <stdint.h> - -/* We should be OK if we don't split the stack here, since we are just - calling memmove which shouldn't need much stack. If we don't do - this we will always split the stack, because of memmove. */ - -extern void -__go_copy (void *, void *, uintptr_t) - __attribute__ ((no_split_stack)); - -void -__go_copy (void *a, void *b, uintptr_t len) -{ - __builtin_memmove (a, b, len); -} diff --git a/libgo/runtime/go-make-slice.c b/libgo/runtime/go-make-slice.c deleted file mode 100644 index ccd07e5..0000000 --- a/libgo/runtime/go-make-slice.c +++ /dev/null @@ -1,99 +0,0 @@ -/* go-make-slice.c -- make a slice. - - Copyright 2011 The Go Authors. All rights reserved. - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. */ - -#include <stdint.h> - -#include "runtime.h" -#include "go-alloc.h" -#include "go-assert.h" -#include "go-panic.h" -#include "go-type.h" -#include "array.h" -#include "arch.h" -#include "malloc.h" - -/* Dummy word to use as base pointer for make([]T, 0). - Since you cannot take the address of such a slice, - you can't tell that they all have the same base pointer. */ -uintptr runtime_zerobase; - -struct __go_open_array -__go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len, - uintptr_t cap) -{ - const struct __go_slice_type* std; - intgo ilen; - intgo icap; - uintptr_t size; - struct __go_open_array ret; - - __go_assert ((td->__code & GO_CODE_MASK) == GO_SLICE); - std = (const struct __go_slice_type *) td; - - ilen = (intgo) len; - if (ilen < 0 - || (uintptr_t) ilen != len - || (std->__element_type->__size > 0 - && len > MaxMem / std->__element_type->__size)) - runtime_panicstring ("makeslice: len out of range"); - - icap = (intgo) cap; - if (cap < len - || (uintptr_t) icap != cap - || (std->__element_type->__size > 0 - && cap > MaxMem / std->__element_type->__size)) - runtime_panicstring ("makeslice: cap out of range"); - - ret.__count = ilen; - ret.__capacity = icap; - - size = cap * std->__element_type->__size; - - if (size == 0) - ret.__values = &runtime_zerobase; - else if ((std->__element_type->__code & GO_NO_POINTERS) != 0) - ret.__values = - runtime_mallocgc (size, - (uintptr) std->__element_type | TypeInfo_Array, - FlagNoScan); - else - ret.__values = - runtime_mallocgc (size, - (uintptr) std->__element_type | TypeInfo_Array, - 0); - - return ret; -} - -struct __go_open_array -__go_make_slice1 (const struct __go_type_descriptor *td, uintptr_t len) -{ - return __go_make_slice2 (td, len, len); -} - -struct __go_open_array -__go_make_slice2_big (const struct __go_type_descriptor *td, uint64_t len, - uint64_t cap) -{ - uintptr_t slen; - uintptr_t scap; - - slen = (uintptr_t) len; - if ((uint64_t) slen != len) - runtime_panicstring ("makeslice: len out of range"); - - scap = (uintptr_t) cap; - if ((uint64_t) scap != cap) - runtime_panicstring ("makeslice: cap out of range"); - - return __go_make_slice2 (td, slen, scap); -} - -struct __go_open_array -__go_make_slice1_big (const struct __go_type_descriptor *td, uint64_t len) -{ - return __go_make_slice2_big (td, len, len); -} diff --git a/libgo/runtime/malloc.goc b/libgo/runtime/malloc.goc index 1fd4461..5cbdc46 100644 --- a/libgo/runtime/malloc.goc +++ b/libgo/runtime/malloc.goc @@ -81,7 +81,7 @@ runtime_mallocgc(uintptr size, uintptr typ, uint32 flag) // All 0-length allocations use this pointer. // The language does not require the allocations to // have distinct values. - return &runtime_zerobase; + return runtime_getZerobase(); } g = runtime_g(); @@ -881,7 +881,7 @@ func new(typ *Type) (ret *uint8) { } static void* -cnew(const Type *typ, intgo n, int32 objtyp) +runtime_docnew(const Type *typ, intgo n, int32 objtyp) { if((objtyp&(PtrSize-1)) != objtyp) runtime_throw("runtime: invalid objtyp"); @@ -894,13 +894,13 @@ cnew(const Type *typ, intgo n, int32 objtyp) void* runtime_cnew(const Type *typ) { - return cnew(typ, 1, TypeInfo_SingleObject); + return runtime_docnew(typ, 1, TypeInfo_SingleObject); } void* runtime_cnewarray(const Type *typ, intgo n) { - return cnew(typ, n, TypeInfo_Array); + return runtime_docnew(typ, n, TypeInfo_Array); } func GC() { diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index 8be0df4..501f1b4 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -234,7 +234,8 @@ enum /* * external data */ -extern uintptr runtime_zerobase; +extern uintptr* runtime_getZerobase(void) + __asm__(GOSYM_PREFIX "runtime.getZerobase"); extern G** runtime_allg; extern uintptr runtime_allglen; extern G* runtime_lastg; |