mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	support theap for T_OBJECT.
* variable.c: now instance variable space has theap supports. obj_ivar_heap_alloc() tries to acquire memory from theap. * debug_counter.h: add some counters for theap. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65451 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									437392232a
								
							
						
					
					
						commit
						873d57347f
					
				
					 6 changed files with 170 additions and 59 deletions
				
			
		|  | @ -141,6 +141,7 @@ RB_DEBUG_COUNTER(gc_major_oldmalloc) | |||
|  * * [attr] | ||||
|  *   * _ptr: R?? is not embed. | ||||
|  *   * _embed: R?? is embed. | ||||
|  *   * _transient: R?? uses transient heap. | ||||
|  * * type specific attr. | ||||
|  *   * str_shared: str is shared. | ||||
|  *   * str_nofree:        nofree | ||||
|  | @ -162,8 +163,9 @@ RB_DEBUG_COUNTER(obj_free) | |||
| RB_DEBUG_COUNTER(obj_promote) | ||||
| RB_DEBUG_COUNTER(obj_wb_unprotect) | ||||
| 
 | ||||
| RB_DEBUG_COUNTER(obj_obj_ptr) | ||||
| RB_DEBUG_COUNTER(obj_obj_embed) | ||||
| RB_DEBUG_COUNTER(obj_obj_transient) | ||||
| RB_DEBUG_COUNTER(obj_obj_ptr) | ||||
| 
 | ||||
| RB_DEBUG_COUNTER(obj_str_ptr) | ||||
| RB_DEBUG_COUNTER(obj_str_embed) | ||||
|  | @ -171,8 +173,9 @@ RB_DEBUG_COUNTER(obj_str_shared) | |||
| RB_DEBUG_COUNTER(obj_str_nofree) | ||||
| RB_DEBUG_COUNTER(obj_str_fstr) | ||||
| 
 | ||||
| RB_DEBUG_COUNTER(obj_ary_ptr) | ||||
| RB_DEBUG_COUNTER(obj_ary_embed) | ||||
| RB_DEBUG_COUNTER(obj_ary_transient) | ||||
| RB_DEBUG_COUNTER(obj_ary_ptr) | ||||
| 
 | ||||
| RB_DEBUG_COUNTER(obj_hash_empty) | ||||
| RB_DEBUG_COUNTER(obj_hash_under4) | ||||
|  |  | |||
							
								
								
									
										38
									
								
								gc.c
									
										
									
									
									
								
							
							
						
						
									
										38
									
								
								gc.c
									
										
									
									
									
								
							|  | @ -2215,13 +2215,16 @@ obj_free(rb_objspace_t *objspace, VALUE obj) | |||
| 
 | ||||
|     switch (BUILTIN_TYPE(obj)) { | ||||
|       case T_OBJECT: | ||||
|         if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) && | ||||
|             RANY(obj)->as.object.as.heap.ivptr) { | ||||
|             xfree(RANY(obj)->as.object.as.heap.ivptr); | ||||
|             RB_DEBUG_COUNTER_INC(obj_obj_ptr); | ||||
|         if ((RANY(obj)->as.basic.flags & ROBJECT_EMBED) || | ||||
|             RANY(obj)->as.object.as.heap.ivptr == NULL) { | ||||
|             RB_DEBUG_COUNTER_INC(obj_obj_embed); | ||||
|         } | ||||
|         else if (ROBJ_TRANSIENT_P(obj)) { | ||||
|             RB_DEBUG_COUNTER_INC(obj_obj_transient); | ||||
|         } | ||||
|         else { | ||||
|             RB_DEBUG_COUNTER_INC(obj_obj_embed); | ||||
|             xfree(RANY(obj)->as.object.as.heap.ivptr); | ||||
|             RB_DEBUG_COUNTER_INC(obj_obj_ptr); | ||||
|         } | ||||
|         break; | ||||
|       case T_MODULE: | ||||
|  | @ -4717,10 +4720,18 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj) | |||
| 
 | ||||
|       case T_OBJECT: | ||||
|         { | ||||
|             const VALUE * const ptr = ROBJECT_IVPTR(obj); | ||||
| 
 | ||||
|             if (ptr) { | ||||
|                 uint32_t i, len = ROBJECT_NUMIV(obj); | ||||
|             VALUE *ptr = ROBJECT_IVPTR(obj); | ||||
|                 for (i  = 0; i < len; i++) { | ||||
|                 gc_mark(objspace, *ptr++); | ||||
|                     gc_mark(objspace, ptr[i]); | ||||
|                 } | ||||
| 
 | ||||
|                 if (objspace->mark_func_data == NULL && | ||||
|                     ROBJ_TRANSIENT_P(obj)) { | ||||
|                     rb_transient_heap_mark(obj, ptr); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 	break; | ||||
|  | @ -9645,6 +9656,19 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj) | |||
| 	    } | ||||
| 	    break; | ||||
| 	  } | ||||
|           case T_OBJECT: | ||||
|             { | ||||
|                 uint32_t len = ROBJECT_NUMIV(obj); | ||||
| 
 | ||||
|                 if (RANY(obj)->as.basic.flags & ROBJECT_EMBED) { | ||||
|                     snprintf(buff, buff_size, "%s (embed) len:%d", buff, len); | ||||
|                 } | ||||
|                 else { | ||||
|                     VALUE *ptr = ROBJECT_IVPTR(obj); | ||||
|                     snprintf(buff, buff_size, "%s len:%d ptr:%p", buff, len, ptr); | ||||
|                 } | ||||
|             } | ||||
|             break; | ||||
| 	  case T_DATA: { | ||||
| 	    const struct rb_block *block; | ||||
| 	    const rb_iseq_t *iseq; | ||||
|  |  | |||
|  | @ -1922,6 +1922,9 @@ extern rb_encoding OnigEncodingUTF_8; | |||
| #endif | ||||
| 
 | ||||
| /* variable.c */ | ||||
| #define ROBJECT_TRANSIENT_FLAG FL_USER13 | ||||
| #define ROBJ_TRANSIENT_P(obj) FL_TEST_RAW((obj), ROBJECT_TRANSIENT_FLAG) | ||||
| 
 | ||||
| void rb_gc_mark_global_tbl(void); | ||||
| size_t rb_generic_ivar_memsize(VALUE); | ||||
| VALUE rb_search_class_path(VALUE); | ||||
|  |  | |||
|  | @ -353,7 +353,8 @@ rb_transient_heap_alloc(VALUE obj, size_t req_size) | |||
|     struct transient_heap* theap = transient_heap_get(); | ||||
|     size_t size = ROUND_UP(req_size + sizeof(struct transient_alloc_header), TRANSIENT_HEAP_ALLOC_ALIGN); | ||||
| 
 | ||||
|     TH_ASSERT(RB_TYPE_P(obj, T_ARRAY)); /* supported types */ | ||||
|     TH_ASSERT(RB_TYPE_P(obj, T_ARRAY) || | ||||
|               RB_TYPE_P(obj, T_OBJECT)); /* supported types */ | ||||
| 
 | ||||
|     if (size > TRANSIENT_HEAP_ALLOC_MAX) { | ||||
|         if (TRANSIENT_HEAP_DEBUG >= 3) fprintf(stderr, "rb_transient_heap_alloc: [too big: %ld] %s\n", (long)size, rb_obj_info(obj)); | ||||
|  | @ -557,6 +558,14 @@ transient_heap_ptr(VALUE obj, int error) | |||
|             ptr = NULL; | ||||
|         } | ||||
|         break; | ||||
|       case T_OBJECT: | ||||
|         if (ROBJ_TRANSIENT_P(obj)) { | ||||
|             ptr = ROBJECT_IVPTR(obj); | ||||
|         } | ||||
|         else { | ||||
|             ptr = NULL; | ||||
|         } | ||||
|         break; | ||||
|       default: | ||||
|         if (error) { | ||||
|             rb_bug("transient_heap_ptr: unknown obj %s\n", rb_obj_info(obj)); | ||||
|  | @ -659,11 +668,10 @@ transient_heap_block_evacuate(struct transient_heap* theap, struct transient_hea | |||
| 
 | ||||
|             switch (BUILTIN_TYPE(obj)) { | ||||
|               case T_ARRAY: | ||||
| #if TRANSIENT_HEAP_DEBUG_DONT_PROMOTE | ||||
|                 rb_ary_transient_heap_evacuate(obj, FALSE); | ||||
| #else | ||||
|                 rb_ary_transient_heap_evacuate(obj, TRUE); | ||||
| #endif | ||||
|                 rb_ary_transient_heap_evacuate(obj, !TRANSIENT_HEAP_DEBUG_DONT_PROMOTE); | ||||
|                 break; | ||||
|               case T_OBJECT: | ||||
|                 rb_obj_transient_heap_evacuate(obj, !TRANSIENT_HEAP_DEBUG_DONT_PROMOTE); | ||||
|                 break; | ||||
|               default: | ||||
|                 rb_bug("unsupporeted"); | ||||
|  |  | |||
|  | @ -34,5 +34,6 @@ int  rb_transient_heap_managed_ptr_p(const void *ptr); | |||
| 
 | ||||
| /* evacuate functions */ | ||||
| void rb_ary_transient_heap_evacuate(VALUE ary, int promote); | ||||
| void rb_obj_transient_heap_evacuate(VALUE ary, int promote); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										98
									
								
								variable.c
									
										
									
									
									
								
							
							
						
						
									
										98
									
								
								variable.c
									
										
									
									
									
								
							|  | @ -22,6 +22,7 @@ | |||
| #include "id_table.h" | ||||
| #include "debug_counter.h" | ||||
| #include "vm_core.h" | ||||
| #include "transient_heap.h" | ||||
| 
 | ||||
| static struct rb_id_table *rb_global_tbl; | ||||
| static ID autoload, classpath, tmp_classpath, classid; | ||||
|  | @ -1333,18 +1334,75 @@ generic_ivar_set(VALUE obj, ID id, VALUE val) | |||
|     RB_OBJ_WRITTEN(obj, Qundef, val); | ||||
| } | ||||
| 
 | ||||
| VALUE | ||||
| rb_ivar_set(VALUE obj, ID id, VALUE val) | ||||
| static VALUE * | ||||
| obj_ivar_heap_alloc(VALUE obj, size_t newsize) | ||||
| { | ||||
|     VALUE *newptr = rb_transient_heap_alloc(obj, sizeof(VALUE) * newsize); | ||||
| 
 | ||||
|     if (newptr != NULL) { | ||||
|         FL_SET_RAW(obj, ROBJECT_TRANSIENT_FLAG); | ||||
|     } | ||||
|     else { | ||||
|         FL_UNSET_RAW(obj, ROBJECT_TRANSIENT_FLAG); | ||||
|         newptr = ALLOC_N(VALUE, newsize); | ||||
|     } | ||||
|     return newptr; | ||||
| } | ||||
| 
 | ||||
| static VALUE * | ||||
| obj_ivar_heap_realloc(VALUE obj, int32_t len, size_t newsize) | ||||
| { | ||||
|     VALUE *newptr; | ||||
|     int i; | ||||
| 
 | ||||
|     if (ROBJ_TRANSIENT_P(obj)) { | ||||
|         const VALUE *orig_ptr = ROBJECT(obj)->as.heap.ivptr; | ||||
|         if ((newptr = obj_ivar_heap_alloc(obj, newsize)) != NULL) { | ||||
|             /* ok */ | ||||
|         } | ||||
|         else { | ||||
|             newptr = ALLOC_N(VALUE, newsize); | ||||
|             FL_UNSET_RAW(obj, ROBJECT_TRANSIENT_FLAG); | ||||
|         } | ||||
|         ROBJECT(obj)->as.heap.ivptr = newptr; | ||||
|         for (i=0; i<(int)len; i++) { | ||||
|             newptr[i] = orig_ptr[i]; | ||||
|         } | ||||
|     } | ||||
|     else { | ||||
|         REALLOC_N(ROBJECT(obj)->as.heap.ivptr, VALUE, newsize); | ||||
|         newptr = ROBJECT(obj)->as.heap.ivptr; | ||||
|     } | ||||
| 
 | ||||
|     return newptr; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| rb_obj_transient_heap_evacuate(VALUE obj, int promote) | ||||
| { | ||||
|     if (ROBJ_TRANSIENT_P(obj)) { | ||||
|         uint32_t len = ROBJECT_NUMIV(obj); | ||||
|         const VALUE *old_ptr = ROBJECT_IVPTR(obj); | ||||
|         VALUE *new_ptr; | ||||
| 
 | ||||
|         if (promote) { | ||||
|             new_ptr = ALLOC_N(VALUE, len); | ||||
|             FL_UNSET_RAW(obj, ROBJECT_TRANSIENT_FLAG); | ||||
|         } | ||||
|         else { | ||||
|             new_ptr = obj_ivar_heap_alloc(obj, len); | ||||
|         } | ||||
|         MEMCPY(new_ptr, old_ptr, VALUE, len); | ||||
|         ROBJECT(obj)->as.heap.ivptr = new_ptr; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static VALUE | ||||
| obj_ivar_set(VALUE obj, ID id, VALUE val) | ||||
| { | ||||
|     struct ivar_update ivup; | ||||
|     uint32_t i, len; | ||||
| 
 | ||||
|     RB_DEBUG_COUNTER_INC(ivar_set_base); | ||||
| 
 | ||||
|     rb_check_frozen(obj); | ||||
| 
 | ||||
|     switch (BUILTIN_TYPE(obj)) { | ||||
|       case T_OBJECT: | ||||
|     ivup.iv_extended = 0; | ||||
|     ivup.u.iv_index_tbl = iv_index_tbl_make(obj); | ||||
|     iv_index_tbl_extend(&ivup, id); | ||||
|  | @ -1363,23 +1421,37 @@ rb_ivar_set(VALUE obj, ID id, VALUE val) | |||
|             uint32_t newsize = iv_index_tbl_newsize(&ivup); | ||||
| 
 | ||||
|             if (RBASIC(obj)->flags & ROBJECT_EMBED) { | ||||
|                     newptr = ALLOC_N(VALUE, newsize); | ||||
|                 newptr = obj_ivar_heap_alloc(obj, newsize); | ||||
|                 // newptr = ALLOC_N(VALUE, newsize);
 | ||||
|                 MEMCPY(newptr, ptr, VALUE, len); | ||||
|                 RBASIC(obj)->flags &= ~ROBJECT_EMBED; | ||||
|                 ROBJECT(obj)->as.heap.ivptr = newptr; | ||||
|             } | ||||
|             else { | ||||
|                     REALLOC_N(ROBJECT(obj)->as.heap.ivptr, VALUE, newsize); | ||||
|                     newptr = ROBJECT(obj)->as.heap.ivptr; | ||||
|                 newptr = obj_ivar_heap_realloc(obj, len, newsize); | ||||
|             } | ||||
|                 for (; len < newsize; len++) | ||||
|             for (; len < newsize; len++) { | ||||
|                 newptr[len] = Qundef; | ||||
|             } | ||||
|             ROBJECT(obj)->as.heap.numiv = newsize; | ||||
|             ROBJECT(obj)->as.heap.iv_index_tbl = ivup.u.iv_index_tbl; | ||||
|         } | ||||
|     } | ||||
|     RB_OBJ_WRITE(obj, &ROBJECT_IVPTR(obj)[ivup.index], val); | ||||
|         break; | ||||
| 
 | ||||
|     return val; | ||||
| } | ||||
| 
 | ||||
| VALUE | ||||
| rb_ivar_set(VALUE obj, ID id, VALUE val) | ||||
| { | ||||
|     RB_DEBUG_COUNTER_INC(ivar_set_base); | ||||
| 
 | ||||
|     rb_check_frozen(obj); | ||||
| 
 | ||||
|     switch (BUILTIN_TYPE(obj)) { | ||||
|       case T_OBJECT: | ||||
|         return obj_ivar_set(obj, id, val); | ||||
|       case T_CLASS: | ||||
|       case T_MODULE: | ||||
|         if (!RCLASS_IV_TBL(obj)) RCLASS_IV_TBL(obj) = st_init_numtable(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 ko1
						ko1