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

Side by Side Diff: src/pkg/runtime/malloc.goc

Issue 6554060: code review 6554060: runtime: add types to MSpan (Closed)
Patch Set: diff -r 4fdee89c5785 https://go.googlecode.com/hg/ Created 12 years, 6 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:
View unified diff | Download patch
« no previous file with comments | « src/pkg/runtime/malloc.h ('k') | src/pkg/runtime/mgc0.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
(...skipping 25 matching lines...) Expand all
36 void *v; 36 void *v;
37 37
38 if(runtime·gcwaiting && g != m->g0 && m->locks == 0) 38 if(runtime·gcwaiting && g != m->g0 && m->locks == 0)
39 runtime·gosched(); 39 runtime·gosched();
40 if(m->mallocing) 40 if(m->mallocing)
41 runtime·throw("malloc/free - deadlock"); 41 runtime·throw("malloc/free - deadlock");
42 m->mallocing = 1; 42 m->mallocing = 1;
43 if(size == 0) 43 if(size == 0)
44 size = 1; 44 size = 1;
45 45
46 if(DebugTypeAtBlockEnd)
47 size += sizeof(uintptr);
48
46 c = m->mcache; 49 c = m->mcache;
47 c->local_nmalloc++; 50 c->local_nmalloc++;
48 if(size <= MaxSmallSize) { 51 if(size <= MaxSmallSize) {
49 // Allocate from mcache free lists. 52 // Allocate from mcache free lists.
50 sizeclass = runtime·SizeToClass(size); 53 sizeclass = runtime·SizeToClass(size);
51 size = runtime·class_to_size[sizeclass]; 54 size = runtime·class_to_size[sizeclass];
52 v = runtime·MCache_Alloc(c, sizeclass, size, zeroed); 55 v = runtime·MCache_Alloc(c, sizeclass, size, zeroed);
53 if(v == nil) 56 if(v == nil)
54 runtime·throw("out of memory"); 57 runtime·throw("out of memory");
55 c->local_alloc += size; 58 c->local_alloc += size;
(...skipping 21 matching lines...) Expand all
77 if (sizeof(void*) == 4 && c->local_total_alloc >= (1<<30)) { 80 if (sizeof(void*) == 4 && c->local_total_alloc >= (1<<30)) {
78 // purge cache stats to prevent overflow 81 // purge cache stats to prevent overflow
79 runtime·lock(&runtime·mheap); 82 runtime·lock(&runtime·mheap);
80 runtime·purgecachedstats(c); 83 runtime·purgecachedstats(c);
81 runtime·unlock(&runtime·mheap); 84 runtime·unlock(&runtime·mheap);
82 } 85 }
83 86
84 if(!(flag & FlagNoGC)) 87 if(!(flag & FlagNoGC))
85 runtime·markallocated(v, size, (flag&FlagNoPointers) != 0); 88 runtime·markallocated(v, size, (flag&FlagNoPointers) != 0);
86 89
90 if(DebugTypeAtBlockEnd)
91 *(uintptr*)((uintptr)v+size-sizeof(uintptr)) = 0;
92
87 m->mallocing = 0; 93 m->mallocing = 0;
88 94
89 if(!(flag & FlagNoProfiling) && (rate = runtime·MemProfileRate) > 0) { 95 if(!(flag & FlagNoProfiling) && (rate = runtime·MemProfileRate) > 0) {
90 if(size >= rate) 96 if(size >= rate)
91 goto profile; 97 goto profile;
92 if(m->mcache->next_sample > size) 98 if(m->mcache->next_sample > size)
93 m->mcache->next_sample -= size; 99 m->mcache->next_sample -= size;
94 else { 100 else {
95 // pick next profile time 101 // pick next profile time
96 // If you change this, also change allocmcache. 102 // If you change this, also change allocmcache.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 if(size) 212 if(size)
207 *size = s->npages<<PageShift; 213 *size = s->npages<<PageShift;
208 return 1; 214 return 1;
209 } 215 }
210 216
211 if((byte*)v >= (byte*)s->limit) { 217 if((byte*)v >= (byte*)s->limit) {
212 // pointers past the last block do not count as pointers. 218 // pointers past the last block do not count as pointers.
213 return 0; 219 return 0;
214 } 220 }
215 221
216 » n = runtime·class_to_size[s->sizeclass]; 222 » n = s->elemsize;
217 if(base) { 223 if(base) {
218 i = ((byte*)v - p)/n; 224 i = ((byte*)v - p)/n;
219 *base = p + i*n; 225 *base = p + i*n;
220 } 226 }
221 if(size) 227 if(size)
222 *size = n; 228 *size = n;
223 229
224 return 1; 230 return 1;
225 } 231 }
226 232
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 if(p+n > h->arena_used) { 449 if(p+n > h->arena_used) {
444 h->arena_used = p+n; 450 h->arena_used = p+n;
445 if(h->arena_used > h->arena_end) 451 if(h->arena_used > h->arena_end)
446 h->arena_end = h->arena_used; 452 h->arena_end = h->arena_used;
447 runtime·MHeap_MapBits(h); 453 runtime·MHeap_MapBits(h);
448 } 454 }
449 ········ 455 ········
450 return p; 456 return p;
451 } 457 }
452 458
459 static Lock settype_lock;
460
461 void
462 runtime·settype_flush(M *m, bool sysalloc)
463 {
464 uintptr *buf, *endbuf;
465 uintptr size, ofs, j, t;
466 uintptr ntypes, nbytes2, nbytes3;
467 uintptr *data2;
468 byte *data3;
469 bool sysalloc3;
470 void *v;
471 uintptr typ, p;
472 MSpan *s;
473
474 buf = m->settype_buf;
475 endbuf = buf + m->settype_bufsize;
476
477 runtime·lock(&settype_lock);
478 while(buf < endbuf) {
479 v = (void*)*buf;
480 *buf = 0;
481 buf++;
482 typ = *buf;
483 buf++;
484
485 // (Manually inlined copy of runtime·MHeap_Lookup)
486 p = (uintptr)v>>PageShift;
487 if(sizeof(void*) == 8)
488 p -= (uintptr)runtime·mheap.arena_start >> PageShift;
489 s = runtime·mheap.map[p];
490
491 if(s->sizeclass == 0) {
492 s->types.compression = MTypes_Single;
493 s->types.data = typ;
494 continue;
495 }
496
497 size = s->elemsize;
498 ofs = ((uintptr)v - (s->start<<PageShift)) / size;
499
500 switch(s->types.compression) {
501 case MTypes_Empty:
502 ntypes = (s->npages << PageShift) / size;
503 nbytes3 = 8*sizeof(uintptr) + 1*ntypes;
504
505 if(!sysalloc) {
506 data3 = runtime·mallocgc(nbytes3, FlagNoPointers , 0, 1);
507 } else {
508 data3 = runtime·SysAlloc(nbytes3);
509 if(0) runtime·printf("settype(0->3): SysAlloc(%x ) --> %p\n", (uint32)nbytes3, data3);
510 }
511
512 s->types.compression = MTypes_Bytes;
513 s->types.sysalloc = sysalloc;
514 s->types.data = (uintptr)data3;
515
516 ((uintptr*)data3)[1] = typ;
517 data3[8*sizeof(uintptr) + ofs] = 1;
518 break;
519
520 case MTypes_Words:
521 ((uintptr*)s->types.data)[ofs] = typ;
522 break;
523
524 case MTypes_Bytes:
525 data3 = (byte*)s->types.data;
526 for(j=1; j<8; j++) {
527 if(((uintptr*)data3)[j] == typ) {
528 break;
529 }
530 if(((uintptr*)data3)[j] == 0) {
531 ((uintptr*)data3)[j] = typ;
532 break;
533 }
534 }
535 if(j < 8) {
536 data3[8*sizeof(uintptr) + ofs] = j;
537 } else {
538 ntypes = (s->npages << PageShift) / size;
539 nbytes2 = ntypes * sizeof(uintptr);
540
541 if(!sysalloc) {
542 data2 = runtime·mallocgc(nbytes2, FlagNo Pointers, 0, 1);
543 } else {
544 data2 = runtime·SysAlloc(nbytes2);
545 if(0) runtime·printf("settype.(3->2): Sy sAlloc(%x) --> %p\n", (uint32)nbytes2, data2);
546 }
547
548 sysalloc3 = s->types.sysalloc;
549
550 s->types.compression = MTypes_Words;
551 s->types.sysalloc = sysalloc;
552 s->types.data = (uintptr)data2;
553
554 // Move the contents of data3 to data2. Then dea llocate data3.
555 for(j=0; j<ntypes; j++) {
556 t = data3[8*sizeof(uintptr) + j];
557 t = ((uintptr*)data3)[t];
558 data2[j] = t;
559 }
560 if(sysalloc3) {
561 nbytes3 = 8*sizeof(uintptr) + 1*ntypes;
562 if(0) runtime·printf("settype.(3->2): Sy sFree(%p,%x)\n", data3, (uint32)nbytes3);
563 runtime·SysFree(data3, nbytes3);
564 }
565
566 data2[ofs] = typ;
567 }
568 break;
569 }
570 }
571 runtime·unlock(&settype_lock);
572
573 m->settype_bufsize = 0;
574 }
575
576 // It is forbidden to use this function if it is possible that
577 // explicit deallocation via calling runtime·free(v) may happen.
578 void
579 runtime·settype(void *v, uintptr t)
580 {
581 M *m1;
582 uintptr *buf;
583 uintptr i;
584 MSpan *s;
585
586 if(t == 0)
587 runtime·throw("settype: zero type");
588
589 m1 = m;
590 buf = m1->settype_buf;
591 i = m1->settype_bufsize;
592 buf[i+0] = (uintptr)v;
593 buf[i+1] = t;
594 i += 2;
595 m1->settype_bufsize = i;
596
597 if(i == nelem(m1->settype_buf)) {
598 runtime·settype_flush(m1, false);
599 }
600
601 if(DebugTypeAtBlockEnd) {
602 s = runtime·MHeap_Lookup(&runtime·mheap, v);
603 *(uintptr*)((uintptr)v+s->elemsize-sizeof(uintptr)) = t;
604 }
605 }
606
607 void
608 runtime·settype_sysfree(MSpan *s)
609 {
610 uintptr ntypes, nbytes;
611
612 if(!s->types.sysalloc)
613 return;
614
615 nbytes = (uintptr)-1;
616
617 switch (s->types.compression) {
618 case MTypes_Words:
619 ntypes = (s->npages << PageShift) / s->elemsize;
620 nbytes = ntypes * sizeof(uintptr);
621 break;
622 case MTypes_Bytes:
623 ntypes = (s->npages << PageShift) / s->elemsize;
624 nbytes = 8*sizeof(uintptr) + 1*ntypes;
625 break;
626 }
627
628 if(nbytes != (uintptr)-1) {
629 if(0) runtime·printf("settype: SysFree(%p,%x)\n", (void*)s->type s.data, (uint32)nbytes);
630 runtime·SysFree((void*)s->types.data, nbytes);
631 }
632 }
633
634 uintptr
635 runtime·gettype(void *v)
636 {
637 MSpan *s;
638 uintptr t, ofs;
639 byte *data;
640
641 s = runtime·MHeap_LookupMaybe(&runtime·mheap, v);
642 if(s != nil) {
643 t = 0;
644 switch(s->types.compression) {
645 case MTypes_Empty:
646 break;
647 case MTypes_Single:
648 t = s->types.data;
649 break;
650 case MTypes_Words:
651 ofs = (uintptr)v - (s->start<<PageShift);
652 t = ((uintptr*)s->types.data)[ofs/s->elemsize];
653 break;
654 case MTypes_Bytes:
655 ofs = (uintptr)v - (s->start<<PageShift);
656 data = (byte*)s->types.data;
657 t = data[8*sizeof(uintptr) + ofs/s->elemsize];
658 t = ((uintptr*)data)[t];
659 break;
660 default:
661 runtime·throw("runtime·gettype: invalid compression kind ");
662 }
663 if(0) {
664 runtime·lock(&settype_lock);
665 runtime·printf("%p -> %d,%X\n", v, (int32)s->types.compr ession, (int64)t);
666 runtime·unlock(&settype_lock);
667 }
668 return t;
669 }
670 return 0;
671 }
672
453 // Runtime stubs. 673 // Runtime stubs.
454 674
455 void* 675 void*
456 runtime·mal(uintptr n) 676 runtime·mal(uintptr n)
457 { 677 {
458 return runtime·mallocgc(n, 0, 1, 1); 678 return runtime·mallocgc(n, 0, 1, 1);
459 } 679 }
460 680
461 func new(typ *Type) (ret *uint8) { 681 func new(typ *Type) (ret *uint8) {
462 uint32 flag = typ->kind&KindNoPointers ? FlagNoPointers : 0; 682 uint32 flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
463 ret = runtime·mallocgc(typ->size, flag, 1, 1); 683 ret = runtime·mallocgc(typ->size, flag, 1, 1);
684
685 if(UseSpanType && !flag) {
686 if(false) {
687 runtime·printf("new %S: %p\n", *typ->string, ret);
688 }
689 runtime·settype(ret, (uintptr)typ | TypeInfo_SingleObject);
690 }
691
464 FLUSH(&ret); 692 FLUSH(&ret);
465 } 693 }
466 694
467 void* 695 void*
468 runtime·stackalloc(uint32 n) 696 runtime·stackalloc(uint32 n)
469 { 697 {
470 // Stackalloc must be called on scheduler stack, so that we 698 // Stackalloc must be called on scheduler stack, so that we
471 // never try to grow the stack during the code that stackalloc runs. 699 // never try to grow the stack during the code that stackalloc runs.
472 // Doing so would cause a deadlock (issue 1547). 700 // Doing so would cause a deadlock (issue 1547).
473 if(g != m->g0) 701 if(g != m->g0)
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 runtime·printf("runtime.SetFinalizer: finalizer already set\n"); 773 runtime·printf("runtime.SetFinalizer: finalizer already set\n");
546 goto throw; 774 goto throw;
547 } 775 }
548 return; 776 return;
549 777
550 badfunc: 778 badfunc:
551 runtime·printf("runtime.SetFinalizer: second argument is %S, not func(%S )\n", *finalizer.type->string, *obj.type->string); 779 runtime·printf("runtime.SetFinalizer: second argument is %S, not func(%S )\n", *finalizer.type->string, *obj.type->string);
552 throw: 780 throw:
553 runtime·throw("runtime.SetFinalizer"); 781 runtime·throw("runtime.SetFinalizer");
554 } 782 }
OLDNEW
« no previous file with comments | « src/pkg/runtime/malloc.h ('k') | src/pkg/runtime/mgc0.c » ('j') | no next file with comments »

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