How many objects are we talking about here?

On Apr 17, 2014, at 5:46 PM, Scott Knight <[email protected]> wrote:

> So when I call my "ruby objects" command it will create an instance of my 
> RubyObjects class and call invoke on it once. In the invoke is where I have 
> this call
> 
>     self.ruby_current_vm = 
> lldb.value(lldb.target.FindFirstGlobalVariable('ruby_current_vm'))
> 
> Then in print_stats it calls into all_objects which does this
> 
> 
>   def all_objects (self):
>     self.heaps_used = self.ruby_current_vm.objspace.heap_pages.used
> 
>     for i in xrange(self.heaps_used):
>       page = self.ruby_current_vm.objspace.heap_pages.sorted[i]
>       print "page %i" % i
> 
>       for j in xrange(page.limit):
>         rvalue = page.start[j].__getattr__('as')
>         flags = rvalue.basic.flags
>         yield rvalue, flags
> 
> So self.ruby_current_vm should already be reused. If I stop the loop through 
> page.limit everything is fast, but with the code within that second for loop 
> things just slow down more and more.
> 
> -Scott
> 
> 
> On Thu, Apr 17, 2014 at 8:40 PM, Greg Clayton <[email protected]> wrote:
> Since you are dealing with a global, you are not tied to a stack frame, so 
> you should be able to cache this value and re-use it:
> 
> 
> 
>     if not self.ruby_current_vm:
>         self.ruby_current_vm = 
> lldb.value(lldb.target.FindFirstGlobalVariable('ruby_current_vm'))
> 
> Then you should be able to use this over and over without re-fetching it. And 
> you should be really fast. Each time you fetch a variable from 
> SBTarget::FindFirstGlobalVariable(), it re-wraps the variable in a new 
> VariableObjectSP which has its own cluster manager. Why? Because you might do 
> something like:
> 
> f = lldb.value(lldb.target.FindFirstGlobalVariable('g_ptr'))
> 
> f = f.a.b.c.d
> 
> Now we need a reference to the ValueObjectSP for "g_ptr" (the underlying 
> variable that roots the entire expression) to stay alive as long as anyone 
> has a reference to anything that is a child of "g_ptr". Here "f" now 
> reference "g_ptr->a.b.c.d", so any value in this chain is correctly reference 
> counted using a ClusterMananger that keeps all of them alive as long as 
> someone has a reference to any of them.
> 
> So if you reuse your "self.ruby_current_vm", you should only have a single 
> ClusterManager and they should stay shared as long as you use them. Currently 
> you are re-creating the root with each call and then referencing a bunch of 
> children which adds new shared references to each cluster manager.
> 
> Let me know how reusing the one instance goes.
> 
> Greg
> 
> 
> On Apr 17, 2014, at 5:22 PM, Scott Knight <[email protected]> wrote:
> 
> > I attached the instruments trace here in case it might be helpful. Seems 
> > like a lot of time is spent in the ClusterManager. It seems like thats 
> > called from all the ValueObject. I do realize that I'm getting values over 
> > and over again in a loop, but it seems to just take longer each time 
> > through the loop. I also attached the python script I'm using in the zip 
> > file as well.
> >
> > -Scott
> >
> >
> > On Thu, Apr 17, 2014 at 7:56 PM, Greg Clayton <[email protected]> wrote:
> > No idea. If you are running this on MacOSX, I would run a time profile in 
> > instruments on it and see what is going on.
> >
> > On Apr 17, 2014, at 4:32 PM, Scott Knight <[email protected]> wrote:
> >
> > > Any of idea why making that call over and over again would seem to slow 
> > > down over time?
> > >
> > > -Scott
> > >
> > > On Apr 17, 2014 7:29 PM, "Greg Clayton" <[email protected]> wrote:
> > > Yep, it is the python keyword... You currently need to use your 
> > > workaround:
> > >
> > > rvalue.__getattr__("as")
> > >
> > > Glad we found it and that there is nothing wrong with the API (we are 
> > > finding children of anonymous unions, phew!).
> > >
> > > Greg
> > >
> > > On Apr 17, 2014, at 3:46 PM, Scott Knight <[email protected]> wrote:
> > >
> > > > typedef struct RVALUE {
> > > >     union {
> > > >       struct {
> > > >           VALUE flags;                /* always 0 for freed obj */
> > > >           struct RVALUE *next;
> > > >       } free;
> > > >       struct RBasic  basic;
> > > >       struct RObject object;
> > > >       struct RClass  klass;
> > > >       struct RFloat  flonum;
> > > >       struct RString string;
> > > >       struct RArray  array;
> > > >       struct RRegexp regexp;
> > > >       struct RHash   hash;
> > > >       struct RData   data;
> > > >       struct RTypedData   typeddata;
> > > >       struct RStruct rstruct;
> > > >       struct RBignum bignum;
> > > >       struct RFile   file;
> > > >       struct RNode   node;
> > > >       struct RMatch  match;
> > > >       struct RRational rational;
> > > >       struct RComplex complex;
> > > >       struct {
> > > >           struct RBasic basic;
> > > >           VALUE v1;
> > > >           VALUE v2;
> > > >           VALUE v3;
> > > >       } values;
> > > >     } as;
> > > > #if GC_DEBUG
> > > >     const char *file;
> > > >     VALUE line;
> > > > #endif
> > > > } RVALUE;
> > > >
> > >
> >
> >
> > <lldb-cpu-time.zip>
> 
> 

_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to