Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(12)

Delta Between Two Patch Sets: src/pkg/runtime/malloc.goc

Issue 10136043: code review 10136043: runtime: refactor mallocgc (Closed)
Left Patch Set: diff -r dc24634de6c5 https://dvyukov%40google.com@code.google.com/p/go/ Created 11 years, 8 months ago
Right Patch Set: diff -r 654ca7de0282 https://dvyukov%40google.com@code.google.com/p/go/ Created 11 years, 8 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/runtime/malloc.h ('k') | src/pkg/runtime/mfinal.c » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // See malloc.h for overview. 5 // See malloc.h for overview.
6 // 6 //
7 // TODO(rsc): double-check stats. 7 // TODO(rsc): double-check stats.
8 8
9 package runtime 9 package runtime
10 #include "runtime.h" 10 #include "runtime.h"
11 #include "arch_GOARCH.h" 11 #include "arch_GOARCH.h"
12 #include "malloc.h" 12 #include "malloc.h"
13 #include "type.h" 13 #include "type.h"
14 #include "typekind.h" 14 #include "typekind.h"
15 #include "race.h" 15 #include "race.h"
16 16 #include "stack.h"
17
18 // Mark mheap as 'no pointers', it does not contain interesting pointers but occ upies ~45K.
19 #pragma dataflag 16
17 MHeap runtime·mheap; 20 MHeap runtime·mheap;
18 21
19 int32 runtime·checking; 22 int32 runtime·checking;
20 23
21 extern MStats mstats; // defined in zruntime_def_$GOOS_$GOARCH.go 24 extern MStats mstats; // defined in zruntime_def_$GOOS_$GOARCH.go
22 25
23 extern volatile intgo runtime·MemProfileRate; 26 extern volatile intgo runtime·MemProfileRate;
24 27
25 // Allocate an object of at least size bytes. 28 // Allocate an object of at least size bytes.
26 // Small objects are allocated from the per-thread cache's free lists. 29 // Small objects are allocated from the per-thread cache's free lists.
27 // Large objects (> 32 kB) are allocated straight from the heap. 30 // Large objects (> 32 kB) are allocated straight from the heap.
28 // If the block will be freed with runtime·free(), typ must be 0. 31 // If the block will be freed with runtime·free(), typ must be 0.
rsc 2013/07/22 18:52:36 s/()//
29 void* 32 void*
30 runtime·mallocgc(uintptr size, uintptr typ, uint32 flag) 33 runtime·mallocgc(uintptr size, uintptr typ, uint32 flag)
31 { 34 {
32 int32 sizeclass; 35 int32 sizeclass;
33 intgo rate; 36 intgo rate;
34 MCache *c; 37 MCache *c;
35 MCacheList *l; 38 MCacheList *l;
36 uintptr npages; 39 uintptr npages;
37 MSpan *s; 40 MSpan *s;
38 MLink *v; 41 MLink *v;
39 42
40 if(runtime·gcwaiting && g != m->g0 && m->locks == 0 && !(flag & FlagNoIn vokeGC)) 43 if(runtime·gcwaiting && g != m->g0 && m->locks == 0 && !(flag & FlagNoIn vokeGC))
41 runtime·gosched(); 44 runtime·gosched();
42 if(size == 0) { 45 if(size == 0) {
43 // All 0-length allocations use this pointer. 46 // All 0-length allocations use this pointer.
44 // The language does not require the allocations to 47 // The language does not require the allocations to
45 // have distinct values. 48 // have distinct values.
46 return &runtime·zerobase; 49 return &runtime·zerobase;
47 } 50 }
48 if(m->mallocing) 51 if(m->mallocing)
49 runtime·throw("malloc/free - deadlock"); 52 runtime·throw("malloc/free - deadlock");
53 // Disable preemption during settype_flush.
54 // We can not use m->mallocing for this, because settype_flush calls mal locgc.
55 m->locks++;
50 m->mallocing = 1; 56 m->mallocing = 1;
51 57
52 if(DebugTypeAtBlockEnd) 58 if(DebugTypeAtBlockEnd)
53 size += sizeof(uintptr); 59 size += sizeof(uintptr);
54 60
55 c = m->mcache; 61 c = m->mcache;
56 if(size <= MaxSmallSize) { 62 if(size <= MaxSmallSize) {
57 // Allocate from mcache free lists. 63 // Allocate from mcache free lists.
58 // Inlined version of SizeToClass(). 64 // Inlined version of SizeToClass().
59 if(size <= 1024-8) 65 if(size <= 1024-8)
60 sizeclass = runtime·size_to_class8[(size+7)>>3]; 66 sizeclass = runtime·size_to_class8[(size+7)>>3];
61 else 67 else
62 sizeclass = runtime·size_to_class128[(size-1024+127) >> 7]; 68 sizeclass = runtime·size_to_class128[(size-1024+127) >> 7];
63 size = runtime·class_to_size[sizeclass]; 69 size = runtime·class_to_size[sizeclass];
64 l = &c->list[sizeclass]; 70 l = &c->list[sizeclass];
65 if(l->list == nil) 71 if(l->list == nil)
66 runtime·MCache_Refill(c, sizeclass); 72 runtime·MCache_Refill(c, sizeclass);
67 v = l->list; 73 v = l->list;
68 l->list = v->next; 74 l->list = v->next;
69 l->nlist--; 75 l->nlist--;
70 » » if(!(flag & FlagNoZeroize)) { 76 » » if(!(flag & FlagNoZero)) {
71 v->next = nil; 77 v->next = nil;
72 // block is zeroed iff second word is zero ... 78 // block is zeroed iff second word is zero ...
73 if(size > sizeof(uintptr) && ((uintptr*)v)[1] != 0) 79 if(size > sizeof(uintptr) && ((uintptr*)v)[1] != 0)
74 runtime·memclr((byte*)v, size); 80 runtime·memclr((byte*)v, size);
75 } 81 }
76 c->local_cachealloc += size; 82 c->local_cachealloc += size;
77 } else { 83 } else {
78 // TODO(rsc): Report tracebacks for very large allocations. 84 // TODO(rsc): Report tracebacks for very large allocations.
79 85
80 // Allocate directly from heap. 86 // Allocate directly from heap.
81 npages = size >> PageShift; 87 npages = size >> PageShift;
82 if((size & PageMask) != 0) 88 if((size & PageMask) != 0)
83 npages++; 89 npages++;
84 » » s = runtime·MHeap_Alloc(&runtime·mheap, npages, 0, 1, !(flag & F lagNoZeroize)); 90 » » s = runtime·MHeap_Alloc(&runtime·mheap, npages, 0, 1, !(flag & F lagNoZero));
85 if(s == nil) 91 if(s == nil)
86 runtime·throw("out of memory"); 92 runtime·throw("out of memory");
87 s->limit = (byte*)(s->start<<PageShift) + size; 93 s->limit = (byte*)(s->start<<PageShift) + size;
88 size = npages<<PageShift; 94 size = npages<<PageShift;
89 v = (void*)(s->start << PageShift); 95 v = (void*)(s->start << PageShift);
90 96
91 // setup for mark sweep 97 // setup for mark sweep
92 runtime·markspan(v, 0, 0, true); 98 runtime·markspan(v, 0, 0, true);
93 } 99 }
94 100
95 if(!(flag & FlagNoGC)) 101 if(!(flag & FlagNoGC))
96 runtime·markallocated(v, size, (flag&FlagNoPointers) != 0); 102 runtime·markallocated(v, size, (flag&FlagNoPointers) != 0);
97 103
98 if(DebugTypeAtBlockEnd) 104 if(DebugTypeAtBlockEnd)
99 *(uintptr*)((uintptr)v+size-sizeof(uintptr)) = typ; 105 *(uintptr*)((uintptr)v+size-sizeof(uintptr)) = typ;
100 106
101 if(UseSpanType && !(flag & FlagNoPointers) && typ != 0) { 107 if(UseSpanType && !(flag & FlagNoPointers) && typ != 0) {
102 uintptr *buf, i; 108 uintptr *buf, i;
103 109
104 buf = m->settype_buf; 110 buf = m->settype_buf;
105 i = m->settype_bufsize; 111 i = m->settype_bufsize;
106 buf[i++] = (uintptr)v; 112 buf[i++] = (uintptr)v;
107 buf[i++] = typ; 113 buf[i++] = typ;
108 m->settype_bufsize = i; 114 m->settype_bufsize = i;
109 } 115 }
110 116
111 m->mallocing = 0; 117 m->mallocing = 0;
112
113 if(UseSpanType && !(flag & FlagNoPointers) && typ != 0 && m->settype_buf size == nelem(m->settype_buf)) 118 if(UseSpanType && !(flag & FlagNoPointers) && typ != 0 && m->settype_buf size == nelem(m->settype_buf))
114 runtime·settype_flush(m, false); 119 runtime·settype_flush(m, false);
120 m->locks--;
121 if(m->locks == 0 && g->preempt) // restore the preemption request in ca se we've cleared it in newstack
122 g->stackguard0 = StackPreempt;
115 123
116 if(!(flag & FlagNoProfiling) && (rate = runtime·MemProfileRate) > 0) { 124 if(!(flag & FlagNoProfiling) && (rate = runtime·MemProfileRate) > 0) {
117 if(size >= rate) 125 if(size >= rate)
118 goto profile; 126 goto profile;
119 if(m->mcache->next_sample > size) 127 if(m->mcache->next_sample > size)
120 m->mcache->next_sample -= size; 128 m->mcache->next_sample -= size;
121 else { 129 else {
122 // pick next profile time 130 // pick next profile time
123 // If you change this, also change allocmcache. 131 // If you change this, also change allocmcache.
124 if(rate > 0x3fffffff) // make 2*rate not overflow 132 if(rate > 0x3fffffff) // make 2*rate not overflow
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 runtime·printf("runtime.SetFinalizer: finalizer already set\n"); 832 runtime·printf("runtime.SetFinalizer: finalizer already set\n");
825 goto throw; 833 goto throw;
826 } 834 }
827 return; 835 return;
828 836
829 badfunc: 837 badfunc:
830 runtime·printf("runtime.SetFinalizer: second argument is %S, not func(%S )\n", *finalizer.type->string, *obj.type->string); 838 runtime·printf("runtime.SetFinalizer: second argument is %S, not func(%S )\n", *finalizer.type->string, *obj.type->string);
831 throw: 839 throw:
832 runtime·throw("runtime.SetFinalizer"); 840 runtime·throw("runtime.SetFinalizer");
833 } 841 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b