Changeset 439 for EcnlProtoTool/trunk/mruby-2.1.1/src/gc.c
- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-2.1.1
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-2.1.1/src/gc.c
r331 r439 11 11 #include <mruby/class.h> 12 12 #include <mruby/data.h> 13 #include <mruby/istruct.h> 13 14 #include <mruby/hash.h> 14 15 #include <mruby/proc.h> … … 110 111 struct RRange range; 111 112 struct RData data; 113 struct RIStruct istruct; 112 114 struct RProc proc; 113 115 struct REnv env; 116 struct RFiber fiber; 114 117 struct RException exc; 115 118 struct RBreak brk; 116 119 #ifdef MRB_WORD_BOXING 120 #ifndef MRB_WITHOUT_FLOAT 117 121 struct RFloat floatv; 122 #endif 118 123 struct RCptr cptr; 119 124 #endif … … 176 181 #define GC_STEP_SIZE 1024 177 182 178 /* white: 0 11, black: 100, gray: 000 */183 /* white: 001 or 010, black: 100, gray: 000 */ 179 184 #define GC_GRAY 0 180 185 #define GC_WHITE_A 1 … … 273 278 } 274 279 280 MRB_API void* 281 mrb_alloca(mrb_state *mrb, size_t size) 282 { 283 struct RString *s; 284 s = (struct RString*)mrb_obj_alloc(mrb, MRB_TT_STRING, mrb->string_class); 285 return s->as.heap.ptr = (char*)mrb_malloc(mrb, size); 286 } 287 288 static mrb_bool 289 heap_p(mrb_gc *gc, struct RBasic *object) 290 { 291 mrb_heap_page* page; 292 293 page = gc->heaps; 294 while (page) { 295 RVALUE *p; 296 297 p = objects(page); 298 if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE].as.basic) { 299 return TRUE; 300 } 301 page = page->next; 302 } 303 return FALSE; 304 } 305 275 306 MRB_API mrb_bool 276 307 mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) { 277 return is_dead(&mrb->gc, object); 308 mrb_gc *gc = &mrb->gc; 309 if (!heap_p(gc, object)) return TRUE; 310 return is_dead(gc, object); 278 311 } 279 312 … … 343 376 #define DEFAULT_GC_INTERVAL_RATIO 200 344 377 #define DEFAULT_GC_STEP_RATIO 200 345 #define DEFAULT_MAJOR_GC_INC_RATIO 200 378 #define MAJOR_GC_INC_RATIO 120 379 #define MAJOR_GC_TOOMANY 10000 346 380 #define is_generational(gc) ((gc)->generational) 347 381 #define is_major_gc(gc) (is_generational(gc) && (gc)->full) … … 374 408 static void obj_free(mrb_state *mrb, struct RBasic *obj, int end); 375 409 376 void410 static void 377 411 free_heap(mrb_state *mrb, mrb_gc *gc) 378 412 { … … 413 447 if (gc->arena_idx >= gc->arena_capa) { 414 448 /* extend arena */ 415 gc->arena_capa = (int)(gc->arena_capa * 1.5);449 gc->arena_capa = (int)(gc->arena_capa * 3 / 2); 416 450 gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa); 417 451 } … … 441 475 mrb_gc_register(mrb_state *mrb, mrb_value obj) 442 476 { 443 mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME); 444 mrb_value table = mrb_gv_get(mrb, root); 445 446 if (mrb_nil_p(table) || mrb_type(table) != MRB_TT_ARRAY) { 477 mrb_sym root; 478 mrb_value table; 479 480 if (mrb_immediate_p(obj)) return; 481 root = mrb_intern_lit(mrb, GC_ROOT_NAME); 482 table = mrb_gv_get(mrb, root); 483 if (mrb_nil_p(table) || !mrb_array_p(table)) { 447 484 table = mrb_ary_new(mrb); 448 485 mrb_gv_set(mrb, root, table); … … 455 492 mrb_gc_unregister(mrb_state *mrb, mrb_value obj) 456 493 { 457 mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);458 mrb_value table = mrb_gv_get(mrb, root);494 mrb_sym root; 495 mrb_value table; 459 496 struct RArray *a; 460 497 mrb_int i; 461 498 499 if (mrb_immediate_p(obj)) return; 500 root = mrb_intern_lit(mrb, GC_ROOT_NAME); 501 table = mrb_gv_get(mrb, root); 462 502 if (mrb_nil_p(table)) return; 463 if ( mrb_type(table) != MRB_TT_ARRAY) {503 if (!mrb_array_p(table)) { 464 504 mrb_gv_set(mrb, root, mrb_nil_value()); 465 505 return; … … 467 507 a = mrb_ary_ptr(table); 468 508 mrb_ary_modify(mrb, a); 469 for (i = 0; i < a->len; i++) { 470 if (mrb_obj_eq(mrb, a->ptr[i], obj)) { 471 a->len--; 472 memmove(&a->ptr[i], &a->ptr[i + 1], (a->len - i) * sizeof(a->ptr[i])); 509 for (i = 0; i < ARY_LEN(a); i++) { 510 if (mrb_ptr(ARY_PTR(a)[i]) == mrb_ptr(obj)) { 511 mrb_int len = ARY_LEN(a)-1; 512 mrb_value *ptr = ARY_PTR(a); 513 514 ARY_SET_LEN(a, len); 515 memmove(&ptr[i], &ptr[i + 1], (len - i) * sizeof(mrb_value)); 473 516 break; 474 517 } … … 480 523 { 481 524 struct RBasic *p; 482 static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } };525 static const RVALUE RVALUE_zero = { { { NULL, NULL, MRB_TT_FALSE } } }; 483 526 mrb_gc *gc = &mrb->gc; 484 527 … … 501 544 ttype != MRB_TT_ENV && 502 545 ttype != tt) { 503 mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of % S", mrb_obj_value(cls));546 mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C", cls); 504 547 } 505 548 } … … 543 586 } 544 587 588 static int 589 ci_nregs(mrb_callinfo *ci) 590 { 591 struct RProc *p = ci->proc; 592 int n = 0; 593 594 if (!p) { 595 if (ci->argc < 0) return 3; 596 return ci->argc+2; 597 } 598 if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { 599 n = p->body.irep->nregs; 600 } 601 if (ci->argc < 0) { 602 if (n < 3) n = 3; /* self + args + blk */ 603 } 604 if (ci->argc > n) { 605 n = ci->argc + 2; /* self + blk */ 606 } 607 return n; 608 } 609 545 610 static void 546 611 mark_context_stack(mrb_state *mrb, struct mrb_context *c) … … 549 614 size_t e; 550 615 mrb_value nil; 551 int nregs;552 616 553 617 if (c->stack == NULL) return; 554 618 e = c->stack - c->stbase; 555 619 if (c->ci) { 556 nregs = c->ci->argc + 2; 557 if (c->ci->nregs > nregs) 558 nregs = c->ci->nregs; 559 e += nregs; 620 e += ci_nregs(c->ci); 560 621 } 561 622 if (c->stbase + e > c->stend) e = c->stend - c->stbase; … … 579 640 int i; 580 641 mrb_callinfo *ci; 642 643 start: 644 if (c->status == MRB_FIBER_TERMINATED) return; 581 645 582 646 /* mark VM stack */ … … 592 656 } 593 657 /* mark ensure stack */ 594 for (i=0; i<c->esize; i++) { 595 if (c->ensure[i] == NULL) break; 658 for (i=0; i<c->eidx; i++) { 596 659 mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); 597 660 } … … 599 662 mrb_gc_mark(mrb, (struct RBasic*)c->fib); 600 663 if (c->prev) { 601 mark_context(mrb, c->prev); 664 c = c->prev; 665 goto start; 602 666 } 603 667 } … … 614 678 { 615 679 struct RClass *c = (struct RClass*)obj; 616 if (MRB_FLAG_TEST(c, MRB_FL AG_IS_ORIGIN))680 if (MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_ORIGIN)) 617 681 mrb_gc_mark_mt(mrb, c); 618 682 mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); … … 641 705 struct RProc *p = (struct RProc*)obj; 642 706 643 mrb_gc_mark(mrb, (struct RBasic*)p-> env);644 mrb_gc_mark(mrb, (struct RBasic*)p-> target_class);707 mrb_gc_mark(mrb, (struct RBasic*)p->upper); 708 mrb_gc_mark(mrb, (struct RBasic*)p->e.env); 645 709 } 646 710 break; … … 651 715 mrb_int i, len; 652 716 653 if (MRB_ENV_STACK_SHARED_P(e)) { 654 if (e->cxt.c->fib) { 655 mrb_gc_mark(mrb, (struct RBasic*)e->cxt.c->fib); 656 } 657 break; 717 if (MRB_ENV_STACK_SHARED_P(e) && e->cxt && e->cxt->fib) { 718 mrb_gc_mark(mrb, (struct RBasic*)e->cxt->fib); 658 719 } 659 720 len = MRB_ENV_STACK_LEN(e); … … 677 738 size_t i, e; 678 739 679 for (i=0,e= a->len; i<e; i++) {680 mrb_gc_mark_value(mrb, a->ptr[i]);740 for (i=0,e=ARY_LEN(a); i<e; i++) { 741 mrb_gc_mark_value(mrb, ARY_PTR(a)[i]); 681 742 } 682 743 } … … 689 750 690 751 case MRB_TT_STRING: 752 if (RSTR_FSHARED_P(obj)) { 753 struct RString *s = (struct RString*)obj; 754 mrb_gc_mark(mrb, (struct RBasic*)s->as.heap.aux.fshared); 755 } 691 756 break; 692 757 693 758 case MRB_TT_RANGE: 694 { 695 struct RRange *r = (struct RRange*)obj; 696 697 if (r->edges) { 698 mrb_gc_mark_value(mrb, r->edges->beg); 699 mrb_gc_mark_value(mrb, r->edges->end); 700 } 701 } 759 mrb_gc_mark_range(mrb, (struct RRange*)obj); 702 760 break; 703 761 … … 728 786 return; 729 787 788 #ifndef MRB_WITHOUT_FLOAT 730 789 case MRB_TT_FLOAT: 731 790 #ifdef MRB_WORD_BOXING … … 733 792 #else 734 793 return; 794 #endif 735 795 #endif 736 796 … … 748 808 mrb_gc_free_mt(mrb, (struct RClass*)obj); 749 809 mrb_gc_free_iv(mrb, (struct RObject*)obj); 810 mrb_mc_clear_by_class(mrb, (struct RClass*)obj); 750 811 break; 751 812 case MRB_TT_ICLASS: 752 if (MRB_FLAG_TEST(obj, MRB_FL AG_IS_ORIGIN))813 if (MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN)) 753 814 mrb_gc_free_mt(mrb, (struct RClass*)obj); 815 mrb_mc_clear_by_class(mrb, (struct RClass*)obj); 754 816 break; 755 817 case MRB_TT_ENV: … … 759 821 if (MRB_ENV_STACK_SHARED_P(e)) { 760 822 /* cannot be freed */ 761 return; 823 e->stack = NULL; 824 break; 762 825 } 763 826 mrb_free(mrb, e->stack); … … 770 833 struct mrb_context *c = ((struct RFiber*)obj)->cxt; 771 834 772 if (!end && c && c != mrb->root_c) { 773 mrb_callinfo *ci = c->ci; 774 mrb_callinfo *ce = c->cibase; 775 776 while (ce <= ci) { 777 struct REnv *e = ci->env; 778 if (e && !is_dead(&mrb->gc, e) && 779 e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) { 780 mrb_env_unshare(mrb, e); 835 if (c && c != mrb->root_c) { 836 if (!end && c->status != MRB_FIBER_TERMINATED) { 837 mrb_callinfo *ci = c->ci; 838 mrb_callinfo *ce = c->cibase; 839 840 while (ce <= ci) { 841 struct REnv *e = ci->env; 842 if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) && 843 e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) { 844 mrb_env_unshare(mrb, e); 845 } 846 ci--; 781 847 } 782 ci--;783 848 } 784 849 mrb_free_context(mrb, c); … … 789 854 case MRB_TT_ARRAY: 790 855 if (ARY_SHARED_P(obj)) 791 mrb_ary_decref(mrb, ((struct RArray*)obj)->a ux.shared);792 else 793 mrb_free(mrb, ((struct RArray*)obj)-> ptr);856 mrb_ary_decref(mrb, ((struct RArray*)obj)->as.heap.aux.shared); 857 else if (!ARY_EMBED_P(obj)) 858 mrb_free(mrb, ((struct RArray*)obj)->as.heap.ptr); 794 859 break; 795 860 … … 808 873 809 874 if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { 810 mrb_irep_decref(mrb, p->body.irep); 875 mrb_irep *irep = p->body.irep; 876 if (end) { 877 mrb_irep_cutref(mrb, irep); 878 } 879 mrb_irep_decref(mrb, irep); 811 880 } 812 881 } … … 814 883 815 884 case MRB_TT_RANGE: 816 mrb_ free(mrb, ((struct RRange*)obj)->edges);885 mrb_gc_free_range(mrb, ((struct RRange*)obj)); 817 886 break; 818 887 … … 858 927 mrb_gc_mark(mrb, (struct RBasic*)mrb->array_class); 859 928 mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class); 860 929 mrb_gc_mark(mrb, (struct RBasic*)mrb->range_class); 930 931 #ifndef MRB_WITHOUT_FLOAT 861 932 mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class); 933 #endif 862 934 mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class); 863 935 mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class); … … 918 990 919 991 case MRB_TT_ENV: 920 children += (int)obj->flags;992 children += MRB_ENV_STACK_LEN(obj); 921 993 break; 922 994 … … 927 999 mrb_callinfo *ci; 928 1000 929 if (!c) break; 1001 if (!c || c->status == MRB_FIBER_TERMINATED) break; 1002 930 1003 /* mark stack */ 931 1004 i = c->stack - c->stbase; 932 if (c->ci) i += c->ci->nregs; 1005 1006 if (c->ci) { 1007 i += ci_nregs(c->ci); 1008 } 933 1009 if (c->stbase + i > c->stend) i = c->stend - c->stbase; 934 1010 children += i; … … 949 1025 { 950 1026 struct RArray *a = (struct RArray*)obj; 951 children += a->len;1027 children += ARY_LEN(a); 952 1028 } 953 1029 break; … … 1190 1266 1191 1267 if (is_major_gc(gc)) { 1192 gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO; 1268 size_t threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; 1269 1193 1270 gc->full = FALSE; 1271 if (threshold < MAJOR_GC_TOOMANY) { 1272 gc->majorgc_old_threshold = threshold; 1273 } 1274 else { 1275 /* too many objects allocated during incremental GC, */ 1276 /* instead of increasing threshold, invoke full GC. */ 1277 mrb_full_gc(mrb); 1278 } 1194 1279 } 1195 1280 else if (is_minor_gc(gc)) { … … 1229 1314 1230 1315 if (is_generational(gc)) { 1231 gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;1316 gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; 1232 1317 gc->full = FALSE; 1233 1318 } … … 1240 1325 { 1241 1326 mrb_full_gc(mrb); 1242 }1243 1244 MRB_API int1245 mrb_gc_arena_save(mrb_state *mrb)1246 {1247 return mrb->gc.arena_idx;1248 }1249 1250 MRB_API void1251 mrb_gc_arena_restore(mrb_state *mrb, int idx)1252 {1253 mrb_gc *gc = &mrb->gc;1254 1255 #ifndef MRB_GC_FIXED_ARENA1256 int capa = gc->arena_capa;1257 1258 if (idx < capa / 2) {1259 capa = (int)(capa * 0.66);1260 if (capa < MRB_GC_ARENA_SIZE) {1261 capa = MRB_GC_ARENA_SIZE;1262 }1263 if (capa != gc->arena_capa) {1264 gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa);1265 gc->arena_capa = capa;1266 }1267 }1268 #endif1269 gc->arena_idx = idx;1270 1327 } 1271 1328 … … 1407 1464 1408 1465 mrb_get_args(mrb, "i", &ratio); 1409 mrb->gc.interval_ratio = ratio;1466 mrb->gc.interval_ratio = (int)ratio; 1410 1467 return mrb_nil_value(); 1411 1468 } … … 1440 1497 1441 1498 mrb_get_args(mrb, "i", &ratio); 1442 mrb->gc.step_ratio = ratio;1499 mrb->gc.step_ratio = (int)ratio; 1443 1500 return mrb_nil_value(); 1444 1501 } … … 1458 1515 else if (!is_generational(gc) && enable) { 1459 1516 incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); 1460 gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;1517 gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; 1461 1518 gc->full = FALSE; 1462 1519 } … … 1523 1580 mrb_bool iterating = mrb->gc.iterating; 1524 1581 1582 mrb_full_gc(mrb); 1525 1583 mrb->gc.iterating = TRUE; 1526 1584 if (iterating) { … … 1535 1593 gc_each_objects(mrb, &mrb->gc, callback, data); 1536 1594 mrb->jmp = prev_jmp; 1537 mrb->gc.iterating = iterating; 1595 mrb->gc.iterating = iterating; 1538 1596 } MRB_CATCH(&c_jmp) { 1539 1597 mrb->gc.iterating = iterating; … … 1554 1612 { 1555 1613 struct RClass *gc; 1614 1615 mrb_static_assert(sizeof(RVALUE) <= sizeof(void*) * 6, 1616 "RVALUE size must be within 6 words"); 1556 1617 1557 1618 gc = mrb_define_module(mrb, "GC");
Note:
See TracChangeset
for help on using the changeset viewer.