Should not need to specialize MapTypeToRootKind just to get default behavior

ASSIGNED
Assigned to

Status

()

enhancement
P5
normal
ASSIGNED
2 months ago
2 months ago

People

(Reporter: sfink, Assigned: sfink)

Tracking

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

Assignee

Description

2 months ago

Right now, if you aren't an actual GC pointer and you wanted a Rooted<T*> for your type, you'd need to specialize MapTypeToRootKind to set your RootKind to Traceable. We do this for JS::Realm* among others. Seems like a nuisance, for us and for embedders.

Comment 2

2 months ago
Pushed by sfink@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/29b1d70e8032
Pointer types should default to RootKind::Traceable unless a more specific RootKind has been set via MapTypeToTraceKind r=jwalden

Updated

2 months ago
Priority: -- → P3
Assignee

Comment 4

2 months ago

Sadly, I don't think this is doable.

The patch I attempted to land is completely bogus -- it would return the right value for MapTypeToRootKind<JSScript*,weirdo type>, but MapTypeToRootKind<JSScript*>::kind would still give Traceable (the wrong result).

I can fix that easily enough (where "easily" == "with strenuous effort and great difficulty and a feeling of foolishness once I boiled it back down to the essence of what was required"). It goes something like this:

template <typename T>
struct MapTypeToRootKind<T*> {
  // For pointers to types that declare a TraceKind data member, use that.
  template <typename U>
  static JS::MapTraceKindToRootKind<U::TraceKind> choose(U*, char);

  // For all other types, fall back to Traceable.
  static MapTypeToRootKind<void> choose(T*, int);

  static const JS::RootKind kind = decltype(choose((T*)nullptr, 'x'))::kind;
};

But that depends on the full type information being available, and if it is not available, it will happily resolve to Traceable. Even worse, this file is typically included before the full type info is available, so will lock in the wrong result. (Identical code loaded later gives a different answer.)

I thought I could fix that by using a hardcoded list of type->TraceKind mappings rather than U::TraceKind, since we already enumerate all of the built-in types, but I'm pretty sure that won't work for subtypes of those explicitly listed types.

In theory, it seems like there might be some way to delay the resolution until the root kind is actually needed, and perhaps even make things fail to compile if you instantiate too early, but I'm giving up on this. It's pretty tough to distinguish between completely unknown types and subtypes that have not yet been defined.

Flags: needinfo?(sphink)
Priority: P3 → P5
You need to log in before you can comment on or make changes to this bug.