~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/runtime/malloc.goc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
package runtime
10
10
#include "runtime.h"
11
11
#include "arch_GOARCH.h"
12
 
#include "stack.h"
13
12
#include "malloc.h"
14
 
#include "defs_GOOS_GOARCH.h"
15
13
#include "type.h"
16
 
 
17
 
#pragma dataflag 16 /* mark mheap as 'no pointers', hiding from garbage collector */
18
 
MHeap runtime·mheap;
19
 
 
20
 
extern MStats mstats;   // defined in extern.go
21
 
 
22
 
extern volatile int32 runtime·MemProfileRate;
 
14
#include "typekind.h"
 
15
#include "race.h"
 
16
 
 
17
MHeap *runtime·mheap;
 
18
 
 
19
int32   runtime·checking;
 
20
 
 
21
extern MStats mstats;   // defined in zruntime_def_$GOOS_$GOARCH.go
 
22
 
 
23
extern volatile intgo runtime·MemProfileRate;
23
24
 
24
25
// Allocate an object of at least size bytes.
25
26
// Small objects are allocated from the per-thread cache's free lists.
27
28
void*
28
29
runtime·mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed)
29
30
{
30
 
        int32 sizeclass, rate;
 
31
        int32 sizeclass;
 
32
        intgo rate;
31
33
        MCache *c;
32
34
        uintptr npages;
33
35
        MSpan *s;
34
36
        void *v;
35
37
 
36
 
        if(runtime·gcwaiting && g != m->g0 && m->locks == 0)
 
38
        if(runtime·gcwaiting && g != m->g0 && m->locks == 0 && dogc)
37
39
                runtime·gosched();
38
40
        if(m->mallocing)
39
41
                runtime·throw("malloc/free - deadlock");
41
43
        if(size == 0)
42
44
                size = 1;
43
45
 
 
46
        if(DebugTypeAtBlockEnd)
 
47
                size += sizeof(uintptr);
 
48
 
44
49
        c = m->mcache;
45
50
        c->local_nmalloc++;
46
51
        if(size <= MaxSmallSize) {
60
65
                npages = size >> PageShift;
61
66
                if((size & PageMask) != 0)
62
67
                        npages++;
63
 
                s = runtime·MHeap_Alloc(&runtime·mheap, npages, 0, 1);
 
68
                s = runtime·MHeap_Alloc(runtime·mheap, npages, 0, 1, zeroed);
64
69
                if(s == nil)
65
70
                        runtime·throw("out of memory");
66
71
                size = npages<<PageShift;
71
76
                // setup for mark sweep
72
77
                runtime·markspan(v, 0, 0, true);
73
78
        }
 
79
 
 
80
        if (sizeof(void*) == 4 && c->local_total_alloc >= (1<<30)) {
 
81
                // purge cache stats to prevent overflow
 
82
                runtime·lock(runtime·mheap);
 
83
                runtime·purgecachedstats(c);
 
84
                runtime·unlock(runtime·mheap);
 
85
        }
 
86
 
74
87
        if(!(flag & FlagNoGC))
75
88
                runtime·markallocated(v, size, (flag&FlagNoPointers) != 0);
76
89
 
 
90
        if(DebugTypeAtBlockEnd)
 
91
                *(uintptr*)((uintptr)v+size-sizeof(uintptr)) = 0;
 
92
 
77
93
        m->mallocing = 0;
78
94
 
79
95
        if(!(flag & FlagNoProfiling) && (rate = runtime·MemProfileRate) > 0) {
95
111
 
96
112
        if(dogc && mstats.heap_alloc >= mstats.next_gc)
97
113
                runtime·gc(0);
 
114
 
 
115
        if(raceenabled) {
 
116
                runtime·racemalloc(v, size, m->racepc);
 
117
                m->racepc = nil;
 
118
        }
98
119
        return v;
99
120
}
100
121
 
130
151
        }
131
152
        prof = runtime·blockspecial(v);
132
153
 
 
154
        if(raceenabled)
 
155
                runtime·racefree(v);
 
156
 
133
157
        // Find size class for v.
134
158
        sizeclass = s->sizeclass;
135
159
        c = m->mcache;
136
160
        if(sizeclass == 0) {
137
161
                // Large object.
138
162
                size = s->npages<<PageShift;
139
 
                *(uintptr*)(s->start<<PageShift) = 1;   // mark as "needs to be zeroed"
 
163
                *(uintptr*)(s->start<<PageShift) = (uintptr)0xfeedfeedfeedfeedll;       // mark as "needs to be zeroed"
140
164
                // Must mark v freed before calling unmarkspan and MHeap_Free:
141
165
                // they might coalesce v into other spans and change the bitmap further.
142
166
                runtime·markfreed(v, size);
143
167
                runtime·unmarkspan(v, 1<<PageShift);
144
 
                runtime·MHeap_Free(&runtime·mheap, s, 1);
 
168
                runtime·MHeap_Free(runtime·mheap, s, 1);
145
169
        } else {
146
170
                // Small object.
147
171
                size = runtime·class_to_size[sizeclass];
148
172
                if(size > sizeof(uintptr))
149
 
                        ((uintptr*)v)[1] = 1;   // mark as "needs to be zeroed"
 
173
                        ((uintptr*)v)[1] = (uintptr)0xfeedfeedfeedfeedll;       // mark as "needs to be zeroed"
150
174
                // Must mark v freed before calling MCache_Free:
151
175
                // it might coalesce v and other blocks into a bigger span
152
176
                // and change the bitmap further.
169
193
        MSpan *s;
170
194
 
171
195
        m->mcache->local_nlookup++;
172
 
        s = runtime·MHeap_LookupMaybe(&runtime·mheap, v);
 
196
        if (sizeof(void*) == 4 && m->mcache->local_nlookup >= (1<<30)) {
 
197
                // purge cache stats to prevent overflow
 
198
                runtime·lock(runtime·mheap);
 
199
                runtime·purgecachedstats(m->mcache);
 
200
                runtime·unlock(runtime·mheap);
 
201
        }
 
202
 
 
203
        s = runtime·MHeap_LookupMaybe(runtime·mheap, v);
173
204
        if(sp)
174
205
                *sp = s;
175
206
        if(s == nil) {
196
227
                return 0;
197
228
        }
198
229
 
199
 
        n = runtime·class_to_size[s->sizeclass];
 
230
        n = s->elemsize;
200
231
        if(base) {
201
232
                i = ((byte*)v - p)/n;
202
233
                *base = p + i*n;
210
241
MCache*
211
242
runtime·allocmcache(void)
212
243
{
213
 
        int32 rate;
 
244
        intgo rate;
214
245
        MCache *c;
215
246
 
216
 
        runtime·lock(&runtime·mheap);
217
 
        c = runtime·FixAlloc_Alloc(&runtime·mheap.cachealloc);
218
 
        mstats.mcache_inuse = runtime·mheap.cachealloc.inuse;
219
 
        mstats.mcache_sys = runtime·mheap.cachealloc.sys;
220
 
        runtime·unlock(&runtime·mheap);
 
247
        runtime·lock(runtime·mheap);
 
248
        c = runtime·FixAlloc_Alloc(&runtime·mheap->cachealloc);
 
249
        mstats.mcache_inuse = runtime·mheap->cachealloc.inuse;
 
250
        mstats.mcache_sys = runtime·mheap->cachealloc.sys;
 
251
        runtime·unlock(runtime·mheap);
 
252
        runtime·memclr((byte*)c, sizeof(*c));
221
253
 
222
254
        // Set first allocation sample size.
223
255
        rate = runtime·MemProfileRate;
230
262
}
231
263
 
232
264
void
233
 
runtime·purgecachedstats(M* m)
 
265
runtime·freemcache(MCache *c)
234
266
{
235
 
        MCache *c;
 
267
        runtime·MCache_ReleaseAll(c);
 
268
        runtime·lock(runtime·mheap);
 
269
        runtime·purgecachedstats(c);
 
270
        runtime·FixAlloc_Free(&runtime·mheap->cachealloc, c);
 
271
        runtime·unlock(runtime·mheap);
 
272
}
236
273
 
 
274
void
 
275
runtime·purgecachedstats(MCache *c)
 
276
{
237
277
        // Protected by either heap or GC lock.
238
 
        c = m->mcache;
239
278
        mstats.heap_alloc += c->local_cachealloc;
240
279
        c->local_cachealloc = 0;
241
280
        mstats.heap_objects += c->local_objects;
274
313
        USED(arena_size);
275
314
        USED(bitmap_size);
276
315
 
 
316
        if((runtime·mheap = runtime·SysAlloc(sizeof(*runtime·mheap))) == nil)
 
317
                runtime·throw("runtime: cannot allocate heap metadata");
 
318
 
277
319
        runtime·InitSizes();
278
320
 
279
 
        limit = runtime·memlimit();
 
321
        // limit = runtime·memlimit();
 
322
        // See https://code.google.com/p/go/issues/detail?id=5049
 
323
        // TODO(rsc): Fix after 1.1.
 
324
        limit = 0;
280
325
 
281
326
        // Set up the allocation arena, a contiguous area of memory where
282
327
        // allocated data will be found.  The arena begins with a bitmap large
283
328
        // enough to hold 4 bits per allocated word.
284
329
        if(sizeof(void*) == 8 && (limit == 0 || limit > (1<<30))) {
285
330
                // On a 64-bit machine, allocate from a single contiguous reservation.
286
 
                // 16 GB should be big enough for now.
 
331
                // 128 GB (MaxMem) should be big enough for now.
287
332
                //
288
333
                // The code will work with the reservation at any address, but ask
289
 
                // SysReserve to use 0x000000f800000000 if possible.
290
 
                // Allocating a 16 GB region takes away 36 bits, and the amd64
 
334
                // SysReserve to use 0x000000c000000000 if possible.
 
335
                // Allocating a 128 GB region takes away 37 bits, and the amd64
291
336
                // doesn't let us choose the top 17 bits, so that leaves the 11 bits
292
 
                // in the middle of 0x00f8 for us to choose.  Choosing 0x00f8 means
293
 
                // that the valid memory addresses will begin 0x00f8, 0x00f9, 0x00fa, 0x00fb.
294
 
                // None of the bytes f8 f9 fa fb can appear in valid UTF-8, and
295
 
                // they are otherwise as far from ff (likely a common byte) as possible.
296
 
                // Choosing 0x00 for the leading 6 bits was more arbitrary, but it
297
 
                // is not a common ASCII code point either.  Using 0x11f8 instead
 
337
                // in the middle of 0x00c0 for us to choose.  Choosing 0x00c0 means
 
338
                // that the valid memory addresses will begin 0x00c0, 0x00c1, ..., 0x0x00df.
 
339
                // In little-endian, that's c0 00, c1 00, ..., df 00. None of those are valid
 
340
                // UTF-8 sequences, and they are otherwise as far away from 
 
341
                // ff (likely a common byte) as possible. An earlier attempt to use 0x11f8 
298
342
                // caused out of memory errors on OS X during thread allocations.
299
343
                // These choices are both for debuggability and to reduce the
300
344
                // odds of the conservative garbage collector not collecting memory
301
345
                // because some non-pointer block of memory had a bit pattern
302
346
                // that matched a memory address.
303
347
                //
304
 
                // Actually we reserve 17 GB (because the bitmap ends up being 1 GB)
305
 
                // but it hardly matters: fc is not valid UTF-8 either, and we have to
306
 
                // allocate 15 GB before we get that far.
 
348
                // Actually we reserve 136 GB (because the bitmap ends up being 8 GB)
 
349
                // but it hardly matters: e0 00 is not valid UTF-8 either.
307
350
                //
308
351
                // If this fails we fall back to the 32 bit memory mechanism
309
 
                arena_size = 16LL<<30;
 
352
                arena_size = MaxMem;
310
353
                bitmap_size = arena_size / (sizeof(void*)*8/4);
311
 
                p = runtime·SysReserve((void*)(0x00f8ULL<<32), bitmap_size + arena_size);
 
354
                p = runtime·SysReserve((void*)(0x00c0ULL<<32), bitmap_size + arena_size);
312
355
        }
313
356
        if (p == nil) {
314
357
                // On a 32-bit machine, we can't typically get away
354
397
        if((uintptr)p & (((uintptr)1<<PageShift)-1))
355
398
                runtime·throw("runtime: SysReserve returned unaligned address");
356
399
 
357
 
        runtime·mheap.bitmap = p;
358
 
        runtime·mheap.arena_start = p + bitmap_size;
359
 
        runtime·mheap.arena_used = runtime·mheap.arena_start;
360
 
        runtime·mheap.arena_end = runtime·mheap.arena_start + arena_size;
 
400
        runtime·mheap->bitmap = p;
 
401
        runtime·mheap->arena_start = p + bitmap_size;
 
402
        runtime·mheap->arena_used = runtime·mheap->arena_start;
 
403
        runtime·mheap->arena_end = runtime·mheap->arena_start + arena_size;
361
404
 
362
405
        // Initialize the rest of the allocator.        
363
 
        runtime·MHeap_Init(&runtime·mheap, runtime·SysAlloc);
 
406
        runtime·MHeap_Init(runtime·mheap, runtime·SysAlloc);
364
407
        m->mcache = runtime·allocmcache();
365
408
 
366
409
        // See if it works.
394
437
                runtime·SysMap(p, n);
395
438
                h->arena_used += n;
396
439
                runtime·MHeap_MapBits(h);
 
440
                if(raceenabled)
 
441
                        runtime·racemapshadow(p, n);
397
442
                return p;
398
443
        }
399
444
        
420
465
                if(h->arena_used > h->arena_end)
421
466
                        h->arena_end = h->arena_used;
422
467
                runtime·MHeap_MapBits(h);
 
468
                if(raceenabled)
 
469
                        runtime·racemapshadow(p, n);
423
470
        }
424
471
        
425
472
        return p;
426
473
}
427
474
 
 
475
static Lock settype_lock;
 
476
 
 
477
void
 
478
runtime·settype_flush(M *mp, bool sysalloc)
 
479
{
 
480
        uintptr *buf, *endbuf;
 
481
        uintptr size, ofs, j, t;
 
482
        uintptr ntypes, nbytes2, nbytes3;
 
483
        uintptr *data2;
 
484
        byte *data3;
 
485
        bool sysalloc3;
 
486
        void *v;
 
487
        uintptr typ, p;
 
488
        MSpan *s;
 
489
 
 
490
        buf = mp->settype_buf;
 
491
        endbuf = buf + mp->settype_bufsize;
 
492
 
 
493
        runtime·lock(&settype_lock);
 
494
        while(buf < endbuf) {
 
495
                v = (void*)*buf;
 
496
                *buf = 0;
 
497
                buf++;
 
498
                typ = *buf;
 
499
                buf++;
 
500
 
 
501
                // (Manually inlined copy of runtime·MHeap_Lookup)
 
502
                p = (uintptr)v>>PageShift;
 
503
                if(sizeof(void*) == 8)
 
504
                        p -= (uintptr)runtime·mheap->arena_start >> PageShift;
 
505
                s = runtime·mheap->map[p];
 
506
 
 
507
                if(s->sizeclass == 0) {
 
508
                        s->types.compression = MTypes_Single;
 
509
                        s->types.data = typ;
 
510
                        continue;
 
511
                }
 
512
 
 
513
                size = s->elemsize;
 
514
                ofs = ((uintptr)v - (s->start<<PageShift)) / size;
 
515
 
 
516
                switch(s->types.compression) {
 
517
                case MTypes_Empty:
 
518
                        ntypes = (s->npages << PageShift) / size;
 
519
                        nbytes3 = 8*sizeof(uintptr) + 1*ntypes;
 
520
 
 
521
                        if(!sysalloc) {
 
522
                                data3 = runtime·mallocgc(nbytes3, FlagNoProfiling|FlagNoPointers, 0, 1);
 
523
                        } else {
 
524
                                data3 = runtime·SysAlloc(nbytes3);
 
525
                                if(data3 == nil)
 
526
                                        runtime·throw("runtime: cannot allocate memory");
 
527
                                if(0) runtime·printf("settype(0->3): SysAlloc(%x) --> %p\n", (uint32)nbytes3, data3);
 
528
                        }
 
529
 
 
530
                        s->types.compression = MTypes_Bytes;
 
531
                        s->types.sysalloc = sysalloc;
 
532
                        s->types.data = (uintptr)data3;
 
533
 
 
534
                        ((uintptr*)data3)[1] = typ;
 
535
                        data3[8*sizeof(uintptr) + ofs] = 1;
 
536
                        break;
 
537
 
 
538
                case MTypes_Words:
 
539
                        ((uintptr*)s->types.data)[ofs] = typ;
 
540
                        break;
 
541
 
 
542
                case MTypes_Bytes:
 
543
                        data3 = (byte*)s->types.data;
 
544
                        for(j=1; j<8; j++) {
 
545
                                if(((uintptr*)data3)[j] == typ) {
 
546
                                        break;
 
547
                                }
 
548
                                if(((uintptr*)data3)[j] == 0) {
 
549
                                        ((uintptr*)data3)[j] = typ;
 
550
                                        break;
 
551
                                }
 
552
                        }
 
553
                        if(j < 8) {
 
554
                                data3[8*sizeof(uintptr) + ofs] = j;
 
555
                        } else {
 
556
                                ntypes = (s->npages << PageShift) / size;
 
557
                                nbytes2 = ntypes * sizeof(uintptr);
 
558
 
 
559
                                if(!sysalloc) {
 
560
                                        data2 = runtime·mallocgc(nbytes2, FlagNoProfiling|FlagNoPointers, 0, 1);
 
561
                                } else {
 
562
                                        data2 = runtime·SysAlloc(nbytes2);
 
563
                                        if(data2 == nil)
 
564
                                                runtime·throw("runtime: cannot allocate memory");
 
565
                                        if(0) runtime·printf("settype.(3->2): SysAlloc(%x) --> %p\n", (uint32)nbytes2, data2);
 
566
                                }
 
567
 
 
568
                                sysalloc3 = s->types.sysalloc;
 
569
 
 
570
                                s->types.compression = MTypes_Words;
 
571
                                s->types.sysalloc = sysalloc;
 
572
                                s->types.data = (uintptr)data2;
 
573
 
 
574
                                // Move the contents of data3 to data2. Then deallocate data3.
 
575
                                for(j=0; j<ntypes; j++) {
 
576
                                        t = data3[8*sizeof(uintptr) + j];
 
577
                                        t = ((uintptr*)data3)[t];
 
578
                                        data2[j] = t;
 
579
                                }
 
580
                                if(sysalloc3) {
 
581
                                        nbytes3 = 8*sizeof(uintptr) + 1*ntypes;
 
582
                                        if(0) runtime·printf("settype.(3->2): SysFree(%p,%x)\n", data3, (uint32)nbytes3);
 
583
                                        runtime·SysFree(data3, nbytes3);
 
584
                                }
 
585
 
 
586
                                data2[ofs] = typ;
 
587
                        }
 
588
                        break;
 
589
                }
 
590
        }
 
591
        runtime·unlock(&settype_lock);
 
592
 
 
593
        mp->settype_bufsize = 0;
 
594
}
 
595
 
 
596
// It is forbidden to use this function if it is possible that
 
597
// explicit deallocation via calling runtime·free(v) may happen.
 
598
void
 
599
runtime·settype(void *v, uintptr t)
 
600
{
 
601
        M *mp;
 
602
        uintptr *buf;
 
603
        uintptr i;
 
604
        MSpan *s;
 
605
 
 
606
        if(t == 0)
 
607
                runtime·throw("settype: zero type");
 
608
 
 
609
        mp = m;
 
610
        buf = mp->settype_buf;
 
611
        i = mp->settype_bufsize;
 
612
        buf[i+0] = (uintptr)v;
 
613
        buf[i+1] = t;
 
614
        i += 2;
 
615
        mp->settype_bufsize = i;
 
616
 
 
617
        if(i == nelem(mp->settype_buf)) {
 
618
                runtime·settype_flush(mp, false);
 
619
        }
 
620
 
 
621
        if(DebugTypeAtBlockEnd) {
 
622
                s = runtime·MHeap_Lookup(runtime·mheap, v);
 
623
                *(uintptr*)((uintptr)v+s->elemsize-sizeof(uintptr)) = t;
 
624
        }
 
625
}
 
626
 
 
627
void
 
628
runtime·settype_sysfree(MSpan *s)
 
629
{
 
630
        uintptr ntypes, nbytes;
 
631
 
 
632
        if(!s->types.sysalloc)
 
633
                return;
 
634
 
 
635
        nbytes = (uintptr)-1;
 
636
 
 
637
        switch (s->types.compression) {
 
638
        case MTypes_Words:
 
639
                ntypes = (s->npages << PageShift) / s->elemsize;
 
640
                nbytes = ntypes * sizeof(uintptr);
 
641
                break;
 
642
        case MTypes_Bytes:
 
643
                ntypes = (s->npages << PageShift) / s->elemsize;
 
644
                nbytes = 8*sizeof(uintptr) + 1*ntypes;
 
645
                break;
 
646
        }
 
647
 
 
648
        if(nbytes != (uintptr)-1) {
 
649
                if(0) runtime·printf("settype: SysFree(%p,%x)\n", (void*)s->types.data, (uint32)nbytes);
 
650
                runtime·SysFree((void*)s->types.data, nbytes);
 
651
        }
 
652
}
 
653
 
 
654
uintptr
 
655
runtime·gettype(void *v)
 
656
{
 
657
        MSpan *s;
 
658
        uintptr t, ofs;
 
659
        byte *data;
 
660
 
 
661
        s = runtime·MHeap_LookupMaybe(runtime·mheap, v);
 
662
        if(s != nil) {
 
663
                t = 0;
 
664
                switch(s->types.compression) {
 
665
                case MTypes_Empty:
 
666
                        break;
 
667
                case MTypes_Single:
 
668
                        t = s->types.data;
 
669
                        break;
 
670
                case MTypes_Words:
 
671
                        ofs = (uintptr)v - (s->start<<PageShift);
 
672
                        t = ((uintptr*)s->types.data)[ofs/s->elemsize];
 
673
                        break;
 
674
                case MTypes_Bytes:
 
675
                        ofs = (uintptr)v - (s->start<<PageShift);
 
676
                        data = (byte*)s->types.data;
 
677
                        t = data[8*sizeof(uintptr) + ofs/s->elemsize];
 
678
                        t = ((uintptr*)data)[t];
 
679
                        break;
 
680
                default:
 
681
                        runtime·throw("runtime·gettype: invalid compression kind");
 
682
                }
 
683
                if(0) {
 
684
                        runtime·lock(&settype_lock);
 
685
                        runtime·printf("%p -> %d,%X\n", v, (int32)s->types.compression, (int64)t);
 
686
                        runtime·unlock(&settype_lock);
 
687
                }
 
688
                return t;
 
689
        }
 
690
        return 0;
 
691
}
 
692
 
428
693
// Runtime stubs.
429
694
 
430
695
void*
433
698
        return runtime·mallocgc(n, 0, 1, 1);
434
699
}
435
700
 
436
 
func new(typ *Type) (ret *uint8) {
437
 
        uint32 flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
438
 
        ret = runtime·mallocgc(typ->size, flag, 1, 1);
 
701
#pragma textflag 7
 
702
void
 
703
runtime·new(Type *typ, uint8 *ret)
 
704
{
 
705
        uint32 flag;
 
706
 
 
707
        if(raceenabled)
 
708
                m->racepc = runtime·getcallerpc(&typ);
 
709
 
 
710
        if(typ->size == 0) {
 
711
                // All 0-length allocations use this pointer.
 
712
                // The language does not require the allocations to
 
713
                // have distinct values.
 
714
                ret = (uint8*)&runtime·zerobase;
 
715
        } else {
 
716
                flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
 
717
                ret = runtime·mallocgc(typ->size, flag, 1, 1);
 
718
 
 
719
                if(UseSpanType && !flag) {
 
720
                        if(false)
 
721
                                runtime·printf("new %S: %p\n", *typ->string, ret);
 
722
                        runtime·settype(ret, (uintptr)typ | TypeInfo_SingleObject);
 
723
                }
 
724
        }
 
725
 
439
726
        FLUSH(&ret);
440
727
}
441
728
 
442
 
void*
443
 
runtime·stackalloc(uint32 n)
444
 
{
445
 
        // Stackalloc must be called on scheduler stack, so that we
446
 
        // never try to grow the stack during the code that stackalloc runs.
447
 
        // Doing so would cause a deadlock (issue 1547).
448
 
        if(g != m->g0)
449
 
                runtime·throw("stackalloc not on scheduler stack");
450
 
 
451
 
        // Stack allocator uses malloc/free most of the time,
452
 
        // but if we're in the middle of malloc and need stack,
453
 
        // we have to do something else to avoid deadlock.
454
 
        // In that case, we fall back on a fixed-size free-list
455
 
        // allocator, assuming that inside malloc all the stack
456
 
        // frames are small, so that all the stack allocations
457
 
        // will be a single size, the minimum (right now, 5k).
458
 
        if(m->mallocing || m->gcing || n == FixedStack) {
459
 
                if(n != FixedStack) {
460
 
                        runtime·printf("stackalloc: in malloc, size=%d want %d", FixedStack, n);
461
 
                        runtime·throw("stackalloc");
462
 
                }
463
 
                return runtime·FixAlloc_Alloc(m->stackalloc);
464
 
        }
465
 
        return runtime·mallocgc(n, FlagNoProfiling|FlagNoGC, 0, 0);
466
 
}
467
 
 
468
 
void
469
 
runtime·stackfree(void *v, uintptr n)
470
 
{
471
 
        if(m->mallocing || m->gcing || n == FixedStack) {
472
 
                runtime·FixAlloc_Free(m->stackalloc, v);
473
 
                return;
474
 
        }
475
 
        runtime·free(v);
 
729
static void*
 
730
cnew(Type *typ, intgo n, int32 objtyp)
 
731
{
 
732
        uint32 flag;
 
733
        void *ret;
 
734
 
 
735
        if((objtyp&(PtrSize-1)) != objtyp)
 
736
                runtime·throw("runtime: invalid objtyp");
 
737
        if(n < 0 || (typ->size > 0 && n > MaxMem/typ->size))
 
738
                runtime·panicstring("runtime: allocation size out of range");
 
739
        if(typ->size == 0 || n == 0) {
 
740
                // All 0-length allocations use this pointer.
 
741
                // The language does not require the allocations to
 
742
                // have distinct values.
 
743
                return &runtime·zerobase;
 
744
        }
 
745
        flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
 
746
        ret = runtime·mallocgc(typ->size*n, flag, 1, 1);
 
747
        if(UseSpanType && !flag) {
 
748
                if(false)
 
749
                        runtime·printf("cnew [%D]%S: %p\n", (int64)n, *typ->string, ret);
 
750
                runtime·settype(ret, (uintptr)typ | objtyp);
 
751
        }
 
752
        return ret;
 
753
}
 
754
 
 
755
// same as runtime·new, but callable from C
 
756
void*
 
757
runtime·cnew(Type *typ)
 
758
{
 
759
        return cnew(typ, 1, TypeInfo_SingleObject);
 
760
}
 
761
 
 
762
void*
 
763
runtime·cnewarray(Type *typ, intgo n)
 
764
{
 
765
        return cnew(typ, n, TypeInfo_Array);
476
766
}
477
767
 
478
768
func GC() {
483
773
        byte *base;
484
774
        uintptr size;
485
775
        FuncType *ft;
486
 
        int32 i, nret;
 
776
        int32 i;
 
777
        uintptr nret;
487
778
        Type *t;
488
779
 
489
780
        if(obj.type == nil) {