lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marvin Humphrey <mar...@rectangular.com>
Subject Re: [lucy-dev] OFFSET globals
Date Wed, 25 Apr 2012 23:03:08 GMT
On Wed, Apr 25, 2012 at 3:27 PM, Nathan Kurz <nate@verse.com> wrote:
> Yes, very helpful.  That's essentially what I determined, but I got
> lost around S_bequeath_methods.  It's difficult reading through the
> sprintf()'s.
>
> Going one layer deeper to the object code level, which symbols are we
> currently using? I think I found where the OFFSETS come in, but I
> haven't figured out how overrides are signalled.

The output of CFC is definitely easier to understand than the code like
S_bequeath_methods() that does the work. :)  Let's look at some generated
code.

Here are TermQuery's methods:

cfish_method_t LUCY_TERMQUERY_METHODS[] = {
    (cfish_method_t)lucy_Obj_make,
    (cfish_method_t)lucy_Obj_get_refcount,
    (cfish_method_t)lucy_Obj_inc_refcount,
    (cfish_method_t)lucy_Obj_dec_refcount,
    (cfish_method_t)lucy_Obj_to_host,
    (cfish_method_t)lucy_Obj_clone,
    (cfish_method_t)lucy_TermQuery_destroy,
    (cfish_method_t)lucy_TermQuery_equals,
    (cfish_method_t)lucy_Obj_compare_to,
    (cfish_method_t)lucy_Obj_hash_sum,
    (cfish_method_t)lucy_Obj_get_vtable,
    (cfish_method_t)lucy_Obj_get_class_name,
    (cfish_method_t)lucy_Obj_is_a,
    (cfish_method_t)lucy_TermQuery_to_string,
    (cfish_method_t)lucy_Obj_to_i64,
    (cfish_method_t)lucy_Obj_to_f64,
    (cfish_method_t)lucy_Obj_to_bool,
    (cfish_method_t)lucy_TermQuery_serialize,
    (cfish_method_t)lucy_TermQuery_deserialize,
    (cfish_method_t)lucy_TermQuery_dump,
    (cfish_method_t)lucy_TermQuery_load,
    (cfish_method_t)lucy_Obj_mimic,
    (cfish_method_t)lucy_TermQuery_make_compiler,
    (cfish_method_t)lucy_Query_set_boost,
    (cfish_method_t)lucy_Query_get_boost,
    (cfish_method_t)lucy_TermQuery_get_field,
    (cfish_method_t)lucy_TermQuery_get_term,
    NULL
};

So, TermQuery overrides the following methods with its own "fresh"
implementations:

    Destroy        <--- Obj
    Equals         <--- Obj
    To_String      <--- Obj
    Serialize      <--- Obj
    Deserialize    <--- Obj
    Make_Compiler  <--- Query

TermQuery inherits many implementations from Obj.  It also inherits two
implementations from Query:

    Set_Boost
    Get_Boost

And then, TermQuery defines two "novel" methods of its own:

    Get_Field
    Get_Term

I wouldn't say that TermQuery "signals" to anyone that it has overridden a
method.  It's more that when somebody invokes a method on a TermQuery -- let's
pick Equals() -- the caller goes to the slot indicated by
Lucy_TermQuery_Equals_OFFSET and uses whatever function pointer happens to be
there.  Here's the actual method invocation code:

static CHY_INLINE chy_bool_t
Lucy_TermQuery_Equals(const lucy_TermQuery *self, lucy_Obj* other) {
    char *const method_address
        = *(char**)self + Lucy_TermQuery_Equals_OFFSET;
    const Lucy_TermQuery_Equals_t method
        = *((Lucy_TermQuery_Equals_t*)method_address);
    return method((lucy_TermQuery*)self, other);
}

Note that *(char**)self is a way of getting at the first member variable of
the lucy_TermQuery struct, which is a VTable*.

The problem that Nick has been working on is how to cut down on the number of
OFFSET vars.  In order to guarantee that certain seemingly innocuous
refactoring actions won't break the ABI, the current release of Lucy generates
a huge number of OFFSET vars -- and they're all exposed as globals in the
DSO.  Under the new design, we will have far fewer OFFSET vars, and when the
build environment supports it, they will not be visible as global symbols in
the DSO.

Marvin Humphrey

Mime
View raw message