Skip to content

Commit

Permalink
add auto-release of object mvars; updates to refcount to chugraph int…
Browse files Browse the repository at this point in the history
…ernal elements and others
  • Loading branch information
gewang committed Dec 5, 2023
1 parent 1edeec6 commit 20349de
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 79 deletions.
6 changes: 3 additions & 3 deletions src/core/chuck_instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4341,12 +4341,12 @@ t_CKBOOL initialize_object( Chuck_Object * object, Chuck_Type * type, Chuck_VM_S
// cast to ugen
ugen->m_multi_chan[i] = (Chuck_UGen *)obj;
// additional reference count
ugen->m_multi_chan[i]->add_ref();
CK_SAFE_ADD_REF(obj);
// owner
ugen->m_multi_chan[i]->owner = ugen;
ugen->m_multi_chan[i]->owner_ugen = ugen;
// ref count
// spencer 2013-5-20: don't add extra ref, to avoid a ref cycle
//ugen->add_ref();
// ugen->add_ref();
}
// TODO: alloc channels for uana
}
Expand Down
42 changes: 16 additions & 26 deletions src/core/chuck_lang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ t_CKBOOL init_class_uana( Chuck_Env * env, Chuck_Type * type )
return FALSE;

// add variables
uana_offset_blob = type_engine_import_mvar( env, "UAnaBlob", "m_blob", FALSE );
uana_offset_blob = type_engine_import_mvar( env, "int", "@m_blobproxy", FALSE );
if( uana_offset_blob == CK_INVALID_OFFSET ) goto error;

// add upchuck
Expand Down Expand Up @@ -1551,10 +1551,8 @@ CK_DLL_DTOR( object_dtor )
// log
EM_log( CK_LOG_ALL, "Object destructor..." );

// get the string
Chuck_String * str = (Chuck_String *)OBJ_MEMBER_UINT(SELF, Object_offset_string);
// release
CK_SAFE_RELEASE( str );
// NOTE the garbage collector should take care of
// string reference at offset Object_offset_string
}


Expand Down Expand Up @@ -2032,34 +2030,26 @@ CK_DLL_CTOR( uanablob_ctor )
OBJ_MEMBER_TIME(SELF, uanablob_offset_when) = 0;

// fvals
Chuck_ArrayFloat * arr8 = new Chuck_ArrayFloat( 8 );
initialize_object( arr8, SHRED->vm_ref->env()->ckt_array, SHRED, VM );
arr8->add_ref();
OBJ_MEMBER_INT(SELF, uanablob_offset_fvals) = (t_CKINT)arr8;
Chuck_ArrayFloat * arrF = new Chuck_ArrayFloat( 8 );
initialize_object( arrF, SHRED->vm_ref->env()->ckt_array, SHRED, VM );
CK_SAFE_ADD_REF( arrF );
OBJ_MEMBER_INT(SELF, uanablob_offset_fvals) = (t_CKINT)arrF;

// cvals
Chuck_ArrayVec2 * arr16 = new Chuck_ArrayVec2( 8 );
initialize_object( arr16, SHRED->vm_ref->env()->ckt_array, SHRED, VM );
arr16->add_ref();
OBJ_MEMBER_INT(SELF, uanablob_offset_cvals) = (t_CKINT)arr16;
// cvals (complex)
Chuck_ArrayVec2 * arrC = new Chuck_ArrayVec2( 8 );
initialize_object( arrC, SHRED->vm_ref->env()->ckt_array, SHRED, VM );
CK_SAFE_ADD_REF( arrC );
OBJ_MEMBER_INT(SELF, uanablob_offset_cvals) = (t_CKINT)arrC;
}

// dtor
CK_DLL_DTOR( uanablob_dtor )
{
// get array
Chuck_ArrayFloat * arr8 = (Chuck_ArrayFloat *)OBJ_MEMBER_INT(SELF, uanablob_offset_fvals);
// release it
arr8->release();
OBJ_MEMBER_INT(SELF, uanablob_offset_fvals) = 0;

// get array
Chuck_ArrayVec2 * arr16 = (Chuck_ArrayVec2 *)OBJ_MEMBER_INT(SELF, uanablob_offset_cvals);
// release it
arr16->release();
OBJ_MEMBER_INT(SELF, uanablob_offset_cvals) = 0;

// set when to 0 for good measure
OBJ_MEMBER_TIME(SELF, uanablob_offset_when) = 0;

// typed object mvars are auto-released | 1.5.2.0
// include uanablob_offset_fvals and uanablob_offset_cvals
}

CK_DLL_MFUN( uanablob_when )
Expand Down
19 changes: 18 additions & 1 deletion src/core/chuck_oo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,24 @@ Chuck_Object::~Chuck_Object()
type = type->parent;
}

// TODO: release class-scope member vars
// release class-scope member vars | 1.5.2.0 (ge) added
Chuck_Type * t = type_ref;
Chuck_Object * obj = NULL;
// for each type in the inheritance chain
while( t )
{
// for each mvar directly in the class
for( t_CKUINT i = 0; i < t->obj_mvars_offsets.size(); i++ )
{
// get the object reference from the offsets
obj = OBJ_MEMBER_OBJECT( this, t->obj_mvars_offsets[i] );
// release
CK_SAFE_RELEASE(obj);
}

// go up to parent type
t = t->parent;
}

// release origin shred
CK_SAFE_RELEASE( origin_shred );
Expand Down
6 changes: 6 additions & 0 deletions src/core/chuck_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4181,6 +4181,12 @@ t_CKTYPE type_engine_check_exp_decl_part2( Chuck_Env * env, a_Exp_Decl decl )
{
// offset
value->offset = env->curr->offset;
// if at class_scope
if( env->class_def && env->class_scope == 0 && isobj(env,type) )
{
// add it to the class | 1.5.2.0 (ge)
env->class_def->obj_mvars_offsets.push_back( value->offset );
}

/*******************************************************************
* spencer: added this into function to provide the same logic path
Expand Down
2 changes: 2 additions & 0 deletions src/core/chuck_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,8 @@ struct Chuck_Type : public Chuck_Object
f_alloc allocator;
// origin hint
ckte_Origin originHint;
// offsets of mvars that are Objects
std::vector<t_CKUINT> obj_mvars_offsets;

// (within-context, e.g., a ck file) dependency tracking | 1.5.0.8
Chuck_Value_Dependency_Graph depends;
Expand Down
79 changes: 49 additions & 30 deletions src/core/chuck_ugen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "chuck_vm.h"
#include "chuck_lang.h"
#include "chuck_errmsg.h"
#include "ugen_xxx.h" // for subgraph ops
using namespace std;


Expand Down Expand Up @@ -212,7 +213,7 @@ void Chuck_UGen::init()
m_sum_v = NULL;
m_current_v = NULL;

owner = NULL;
owner_ugen = NULL;

// what a hack
m_is_uana = FALSE;
Expand Down Expand Up @@ -256,13 +257,28 @@ void Chuck_UGen::done()
CK_SAFE_DELETE_ARRAY( m_sum_v );
CK_SAFE_DELETE_ARRAY( m_current_v );

// for each multichan reference | 1.5.2.0
for( t_CKUINT i = 0; i < m_multi_chan_size; i++ )
{
// TODO: disconnect?

// release
CK_SAFE_RELEASE( m_multi_chan[i] );
}

// more reclaim (added 1.3.0.0)
CK_SAFE_DELETE_ARRAY( m_multi_chan );
// TODO: m_multi_chan, break ref count loop
CK_SAFE_DELETE_ARRAY( m_multi_chan );
// zero out
m_multi_chan_size = 0;

// SPENCER: is this okay??? (added 1.3.0.0)
// changed to release | 1.5.2.0 (ge)
CK_SAFE_RELEASE( m_inlet );
CK_SAFE_RELEASE( m_outlet );

// SPENCERTODO: is this okay??? (added 1.3.0.0)
CK_SAFE_DELETE( m_inlet );
CK_SAFE_DELETE( m_outlet );
// clean up inlet/outlet | 1.5.2.0 (ge)
if( m_is_subgraph ) ck_subgraph_cleaup_inlet_outlet( this );

// clean up array (added 1.3.0.0)
CK_SAFE_DELETE_ARRAY( m_multi_in_v );
Expand Down Expand Up @@ -308,19 +324,21 @@ void Chuck_UGen::alloc_multi_chan( t_CKUINT num_ins, t_CKUINT num_outs )
{
// get max of num_ins and num_outs
m_multi_chan_size = ( num_ins > num_outs ? num_ins : num_outs );

// allocate
m_multi_chan = new Chuck_UGen *[m_multi_chan_size];
// zero it out, whoever call this will fill in
memset( m_multi_chan, 0, m_multi_chan_size * sizeof(Chuck_UGen *) );
// assert null (no auto-cleanup of any existing m_multi_chan array)
assert( m_multi_chan == NULL );

// mono
if( m_multi_chan_size == 1 )
{
// zero out
m_multi_chan_size = 0;
// self
m_multi_chan[0] = this;
}
else // not mono
{
// allocate
m_multi_chan = new Chuck_UGen *[m_multi_chan_size];
// zero it out, whoever call this will fill in
memset( m_multi_chan, 0, m_multi_chan_size * sizeof(Chuck_UGen *) );
}

// if there tick-frame (i.e., has multi-channel tick function; added 1.3.0.0)
Expand Down Expand Up @@ -433,7 +451,7 @@ void Chuck_UGen::get_buffer( SAMPLE * buffer, t_CKINT num_elem )
//-----------------------------------------------------------------------------
Chuck_UGen * Chuck_UGen::src_chan( t_CKUINT chan )
{
if( this->m_num_outs == 1)
if( this->m_num_outs == 1 )
return this;
return m_multi_chan[chan%m_num_outs];
}
Expand All @@ -448,7 +466,7 @@ Chuck_UGen * Chuck_UGen::src_chan( t_CKUINT chan )
//-----------------------------------------------------------------------------
Chuck_UGen * Chuck_UGen::dst_for_src_chan( t_CKUINT chan )
{
if( this->m_num_ins == 1)
if( this->m_num_ins == 1 )
return this;
if( chan < this->m_num_ins )
return m_multi_chan[chan];
Expand Down Expand Up @@ -955,13 +973,13 @@ t_CKBOOL Chuck_UGen::system_tick( t_CKTIME now )
}

// if owner (i.e., this ugen is one of the channels in a multi-channel ugen)
if( owner != NULL && owner->m_time < now )
if( owner_ugen != NULL && owner_ugen->m_time < now )
{
// tick the owner
owner->system_tick( now );
owner_ugen->system_tick( now );

// if the owner has a multichannel tick function (added 1.3.0.0)
if( owner->tickf )
if( owner_ugen->tickf )
{
// set the latest to the current
m_last = m_current;
Expand Down Expand Up @@ -1166,12 +1184,12 @@ t_CKBOOL Chuck_UGen::system_tick_v( t_CKTIME now, t_CKUINT numFrames )
}

// if owner
if( owner != NULL && owner->m_time < now )
if( owner_ugen != NULL && owner_ugen->m_time < now )
{
owner->system_tick_v( now, numFrames );
owner_ugen->system_tick_v( now, numFrames );

// if the owner has a multichannel tick function (added 1.3.0.0)
if( owner->tickf )
if( owner_ugen->tickf )
{
// set the latest to the current
m_last = m_current_v[numFrames - 1];
Expand Down Expand Up @@ -1333,22 +1351,22 @@ void Chuck_UGen::init_subgraph()
// set as inlet
m_inlet = (Chuck_UGen *)obj;
// additional reference count
m_inlet->add_ref();
CK_SAFE_ADD_REF(m_inlet);
// owner
m_inlet->owner = this;
// ref count
this->add_ref();
m_inlet->owner_ugen = this;
// no ref count | to avoid ref cycle | 1.5.2.0
// CK_SAFE_ADD_REF(this);

// instantiate object for outlet
obj = instantiate_and_initialize_object( this->origin_shred->vm_ref->env()->ckt_ugen, this->origin_shred );
// set as outlet
m_outlet = (Chuck_UGen *)obj;
// additional reference count
m_outlet->add_ref();
CK_SAFE_ADD_REF(m_outlet);
// owner
m_outlet->owner = this;
// ref count
this->add_ref();
m_outlet->owner_ugen = this;
// no ref count | to avoid ref cycle | 1.5.2.0
// CK_SAFE_ADD_REF(this);
}


Expand Down Expand Up @@ -1542,10 +1560,11 @@ t_CKBOOL Chuck_UAna::system_tock( t_CKTIME now )
}

// if owner
if( owner != NULL && owner->m_is_uana )
if( owner_ugen != NULL && owner_ugen->m_is_uana )
{
// cast to uana
uana = (Chuck_UAna *)owner;
// (requires RTT) dynamic_cast<Chuck_UAna *>(owner_ugen);
uana = (Chuck_UAna *)owner_ugen;
// tock it
if( uana->m_uana_time < now ) uana->system_tock( now );
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/chuck_ugen.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ struct Chuck_UGen : public Chuck_Object
SAMPLE * m_current_v;

// owner
Chuck_UGen * owner;
Chuck_UGen * owner_ugen;

// what a hack!
t_CKBOOL m_is_uana;
Expand Down
Loading

0 comments on commit 20349de

Please sign in to comment.