|  | /* go-memclr.c -- clear a memory buffer | 
|  |  | 
|  | Copyright 2016 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" | 
|  |  | 
|  | void memclrNoHeapPointers(void *, uintptr) | 
|  | __asm__ (GOSYM_PREFIX "runtime.memclrNoHeapPointers") | 
|  | __attribute__ ((no_split_stack)); | 
|  |  | 
|  | void | 
|  | memclrNoHeapPointers (void *p1, uintptr len) | 
|  | { | 
|  |  | 
|  | #if !defined(__PPC64__) | 
|  | __builtin_memset(p1, 0, len); | 
|  | #else | 
|  | int64 rem,drem,i; | 
|  | uint64 offset; | 
|  | volatile uint64 *vp; | 
|  |  | 
|  | if (len == 0) { | 
|  | return; | 
|  | } | 
|  | rem = len; | 
|  |  | 
|  | offset = (uint64)p1 % 8; | 
|  | // This memset is OK since it can't contain | 
|  | // an 8 byte aligned pointer. | 
|  | if ((rem < 8) || (offset > 0 && offset+rem <= 16)) { | 
|  | __builtin_memset(p1, 0, rem); | 
|  | return; | 
|  | } | 
|  | // Move initial bytes to get to 8 byte boundary | 
|  | if (offset > 0) { | 
|  | __builtin_memset(p1, 0, 8-offset); | 
|  | p1 = (void*)((char*)p1+8-offset); | 
|  | rem -= 8-offset; | 
|  | } | 
|  |  | 
|  | // If at least 8 bytes left, clear | 
|  | drem = rem>>3; | 
|  |  | 
|  | vp = (volatile uint64*)(p1); | 
|  | // Without the use of volatile here, the compiler | 
|  | // might convert the loop into a memset. | 
|  | for (i=0; i<drem; i++) { | 
|  | *vp = 0; | 
|  | vp++; | 
|  | rem -= 8; | 
|  | } | 
|  | p1 = (void*)((char*)p1 + 8*drem); | 
|  | // Clear any remaining | 
|  | if (rem > 0) { | 
|  | __builtin_memset (p1, 0, rem); | 
|  | } | 
|  | #endif | 
|  | } |