@@ -1654,6 +1654,16 @@ heap_get_freeobj_from_next_freepage(rb_objspace_t *objspace, rb_heap_t *heap)
16541654 return p ;
16551655}
16561656
1657+ static inline VALUE
1658+ heap_get_freeobj_head (rb_objspace_t * objspace , rb_heap_t * heap )
1659+ {
1660+ RVALUE * p = heap -> freelist ;
1661+ if (LIKELY (p != NULL )) {
1662+ heap -> freelist = p -> as .free .next ;
1663+ }
1664+ return (VALUE )p ;
1665+ }
1666+
16571667static inline VALUE
16581668heap_get_freeobj (rb_objspace_t * objspace , rb_heap_t * heap )
16591669{
@@ -1683,44 +1693,17 @@ gc_event_hook_body(rb_thread_t *th, rb_objspace_t *objspace, const rb_event_flag
16831693 EXEC_EVENT_HOOK (th , event , th -> cfp -> self , 0 , 0 , data );
16841694}
16851695
1696+ #define gc_event_hook_needed_p (objspace , event ) ((objspace)->hook_events & (event))
1697+
16861698#define gc_event_hook (objspace , event , data ) do { \
1687- if (UNLIKELY(( objspace)->hook_events & ( event) )) { \
1699+ if (gc_event_hook_needed_p( objspace, event)) { \
16881700 gc_event_hook_body(GET_THREAD(), (objspace), (event), (data)); \
16891701 } \
16901702} while (0)
16911703
1692- static VALUE
1693- newobj_of ( VALUE klass , VALUE flags , VALUE v1 , VALUE v2 , VALUE v3 )
1704+ static inline VALUE
1705+ newobj_of_init ( rb_objspace_t * objspace , VALUE klass , VALUE flags , VALUE v1 , VALUE v2 , VALUE v3 , VALUE obj , int hook_needed )
16941706{
1695- rb_objspace_t * objspace = & rb_objspace ;
1696- VALUE obj ;
1697-
1698- #if GC_DEBUG_STRESS_TO_CLASS
1699- if (UNLIKELY (stress_to_class )) {
1700- long i , cnt = RARRAY_LEN (stress_to_class );
1701- const VALUE * ptr = RARRAY_CONST_PTR (stress_to_class );
1702- for (i = 0 ; i < cnt ; ++ i ) {
1703- if (klass == ptr [i ]) rb_memerror ();
1704- }
1705- }
1706- #endif
1707-
1708- if (UNLIKELY (during_gc || ruby_gc_stressful )) {
1709- if (during_gc ) {
1710- dont_gc = 1 ;
1711- during_gc = 0 ;
1712- rb_bug ("object allocation during garbage collection phase" );
1713- }
1714-
1715- if (ruby_gc_stressful ) {
1716- if (!garbage_collect (objspace , FALSE, FALSE, FALSE, GPR_FLAG_NEWOBJ )) {
1717- rb_memerror ();
1718- }
1719- }
1720- }
1721-
1722- obj = heap_get_freeobj (objspace , heap_eden );
1723-
17241707 if (RGENGC_CHECK_MODE > 0 ) assert (BUILTIN_TYPE (obj ) == T_NONE );
17251708
17261709 /* OBJSETUP */
@@ -1773,7 +1756,10 @@ newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3)
17731756#endif
17741757
17751758 objspace -> total_allocated_objects ++ ;
1776- gc_event_hook (objspace , RUBY_INTERNAL_EVENT_NEWOBJ , obj );
1759+
1760+ if (hook_needed ) {
1761+ gc_event_hook (objspace , RUBY_INTERNAL_EVENT_NEWOBJ , obj );
1762+ }
17771763 gc_report (5 , objspace , "newobj: %s\n" , obj_info (obj ));
17781764
17791765#if RGENGC_OLD_NEWOBJ_CHECK > 0
@@ -1798,6 +1784,57 @@ newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3)
17981784 return obj ;
17991785}
18001786
1787+ NOINLINE (static VALUE newobj_of_slowpass (rb_objspace_t * objspace , VALUE klass , VALUE flags , VALUE v1 , VALUE v2 , VALUE v3 , int hook_needed ));
1788+
1789+ static VALUE
1790+ newobj_of_slowpass (rb_objspace_t * objspace , VALUE klass , VALUE flags , VALUE v1 , VALUE v2 , VALUE v3 , int hook_needed )
1791+ {
1792+ VALUE obj ;
1793+
1794+ if (UNLIKELY (during_gc || ruby_gc_stressful )) {
1795+ if (during_gc ) {
1796+ dont_gc = 1 ;
1797+ during_gc = 0 ;
1798+ rb_bug ("object allocation during garbage collection phase" );
1799+ }
1800+
1801+ if (ruby_gc_stressful ) {
1802+ if (!garbage_collect (objspace , FALSE, FALSE, FALSE, GPR_FLAG_NEWOBJ )) {
1803+ rb_memerror ();
1804+ }
1805+ }
1806+ }
1807+
1808+ obj = heap_get_freeobj (objspace , heap_eden );
1809+ return newobj_of_init (objspace , klass , flags , v1 , v2 , v3 , obj , hook_needed );
1810+ }
1811+
1812+ static VALUE
1813+ newobj_of (VALUE klass , VALUE flags , VALUE v1 , VALUE v2 , VALUE v3 )
1814+ {
1815+ rb_objspace_t * objspace = & rb_objspace ;
1816+ VALUE obj ;
1817+ int hook_needed = gc_event_hook_needed_p (objspace , RUBY_INTERNAL_EVENT_NEWOBJ );
1818+
1819+ #if GC_DEBUG_STRESS_TO_CLASS
1820+ if (UNLIKELY (stress_to_class )) {
1821+ long i , cnt = RARRAY_LEN (stress_to_class );
1822+ const VALUE * ptr = RARRAY_CONST_PTR (stress_to_class );
1823+ for (i = 0 ; i < cnt ; ++ i ) {
1824+ if (klass == ptr [i ]) rb_memerror ();
1825+ }
1826+ }
1827+ #endif
1828+
1829+ if (LIKELY (!(during_gc || ruby_gc_stressful ) && hook_needed == FALSE &&
1830+ (obj = heap_get_freeobj_head (objspace , heap_eden )) != Qfalse )) {
1831+ return newobj_of_init (objspace , klass , flags , v1 , v2 , v3 , obj , FALSE);
1832+ }
1833+ else {
1834+ return newobj_of_slowpass (objspace , klass , flags , v1 , v2 , v3 , hook_needed );
1835+ }
1836+ }
1837+
18011838VALUE
18021839rb_newobj (void )
18031840{
0 commit comments