Ticket #528 (closed roadmap: fixed)

Opened 6 years ago

Last modified 5 years ago

Clone and Modify in DynPMC VTABLE Initialization

Reported by: chromatic Owned by: chromatic
Priority: normal Milestone: 1.2
Component: none Version:
Severity: medium Keywords:
Cc: Language:
Patch status: Platform: all

Description

libparrot exports thousands of symbols. Many of those are the vtable functions in our PMCs. They get exported because of the way initializing a PMC builds its vtable. Look in src/pmc/class.c in a built Parrot source tree for now. Parrot_Class_class_init() creates the Class PMC's vtable as an array of function pointers. Because Class inherits some behavior from the Default PMC, its vtable array contains pointers to functions declared in Default.

That doesn't imply anything about the visibility of those symbols... except that dynpmcs have the same strategy. Every dynpmc either reimplements its own functions, or its initialization code has to refer to symbols explicitly exported from libparrot to get at the function pointers directly from the Default PMC, or whichever core PMC is its parent.

We need a way to map the appropriate slot in the vtable array for each overridden entry. That's easy. We need a way for a dynpmc to access and clone its parent's vtable. That's a little bit more work, if only because we have to do this in generated code, and it's a divergence between how dynpmcs initialize their vtables and how built-in PMCs initialize their vtables.

Core PMCs all get stuffed into the same libparrot, so all of the necessary symbols are visible.

I've already checked in code which initializes PMC vtables in the proper order: parents before children. When we load a dynpmc group, all of Parrot's vtables are assembled properly. The group initializes all of its dynpmcs in the proper order.

When dynpmcs no longer access vtable functions directly, we can remove PARROT_EXPORT from the generated vtable functions -- that's the goal of this exercise.

Change History

  Changed 6 years ago by chromatic

  • status changed from new to assigned
  • summary changed from RFC to Clone and Modify in DynPMC VTABLE Initialization

in reply to: ↑ description ; follow-up: ↓ 3   Changed 5 years ago by cotto

Replying to chromatic:

We need a way to map the appropriate slot in the vtable array for each overridden entry. That's easy. We need a way for a dynpmc to access and clone its parent's vtable. That's a little bit more work, if only because we have to do this in generated code, and it's a divergence between how dynpmcs initialize their vtables and how built-in PMCs initialize their vtables.

Why does there need to be a divergence? It sounds like this approach would work just fine for built-in PMCs too, if perhaps with a slightly higher runtime cost.

in reply to: ↑ 2   Changed 5 years ago by bacek

Replying to cotto:

Replying to chromatic:

We need a way to map the appropriate slot in the vtable array for each overridden entry. That's easy. We need a way for a dynpmc to access and clone its parent's vtable. That's a little bit more work, if only because we have to do this in generated code, and it's a divergence between how dynpmcs initialize their vtables and how built-in PMCs initialize their vtables.

Why does there need to be a divergence? It sounds like this approach would work just fine for built-in PMCs too, if perhaps with a slightly higher runtime cost.

Ok. There is suggestion:

1. Split class_init into 3 functions: get_vtable , build_vtable and init_mro.

2. build_vtable for all classes except "default" will be something like:

build_vtable(VTABLE * table) {
   table[n] = Parrot_derived_foo;
   table[k] = Parrot_derived_bar;
   return table;
}

3. get_vtable will be

VTABLE * get_vtable() {
    return Derived_build_vtable(Parent1_build_vtable(Parent2_build_vtable(Default_build_vtable())));
}

4. setup_mro is "second pass" from current class_init.

With this approach we have to export maximum 2 functions from PMC. DynPMCs will not be different from CorePMCs and use same approach.

-- Bacek

follow-up: ↓ 5   Changed 5 years ago by cotto

I've started the tt528_vtinit branch to work on this.

in reply to: ↑ 4   Changed 5 years ago by cotto

  • status changed from assigned to closed
  • resolution set to fixed

Replying to cotto:

I've started the tt528_vtinit branch to work on this.

The branch has been merged. Thanks to much help from bacek++, the tt528_vtinit branch is passing all tests as of r38468, apart from some pmc2c tests which will need to be updated. particle++ was kind enough to test with msvc 2008, with the same result. With r38469, rakudo also builds.

The branch didn't split up class_init, but it did push vtable initialization down to runtime and remove PARROT_EXPORT from all VTABLE functions. Since that last part was the point of this ticket, I'm marking it resolved.

Note: See TracTickets for help on using tickets.