Contain the impact of conservatively scanning C++ stack frames

NEW
Unassigned

Status

Tamarin
Garbage Collection (mmGC)
P3
normal
8 years ago
6 years ago

People

(Reporter: Lars T Hansen, Unassigned)

Tracking

(Depends on: 4 bugs, Blocks: 1 bug)

unspecified
Q1 12 - Brannan
Dependency tree / graph
Bug Flags:
flashplayer-qrb +

Details

(Whiteboard: Tracking)

(Reporter)

Description

8 years ago
Assuming that we continue to use GC'd storage as extensively throughout the VM and the Flash Player as we currently are using it, it is almost certainly the case that we will forever be scanning C++ stack frames conservatively.  (The alternative would be some combination of system-wide iron discipline and behind-the-scenes tracking of pointers in GCRefs, and perhaps mandatory GCRef use.  I just don't see it being cost-effective or practical.)  So how can we reduce the impact of that conservative scanning?  Some obvious examples:

 - rewrite C++ code as AS3 code to sidestep the issue

 - jit-compile what are now C++ helpers whose frames appear inbetween jit
   frames, so that we can control those frame layouts

 - make a distinction between "harmless" C++ frames (frames that don't need
   to be scanned (at all, or conservatively) because they obey the necessary
   iron discipline, eg by explicitly enregistering all pointers to GC storage)
   and "unknown" frames that must be scanned conservatively, and try to
   postpone stack scanning if the stack has just a few "unknown" frames on it
   in the hope that they will be popped soon.  ("Postponing" can be made
   affordable by starting to check for a good scanning point earlier than we
   would if we were following current GC policy strictly.)

 - static analysis of C++ frames may allow us to create exact tracers for those
   frames, but obviously this is platform-dependent and brittle.  The platforms
   that matter are all mobile, sometimes with highly optimizing non-GCC
   compilers, sometimes with unusual operating systems.

 - avoid alloca() by moving to other temp-memory mechanisms, eg, temp-memory
   managers attached to a GC might work well in practice.

That is, reduce the amount of C++ stack memory that must be scanned conservatively as much as possible, and then start thinking about how to not scan the stack when there is any stack memory that must be scanned conservatively.
(Reporter)

Comment 1

8 years ago
Another problem is that we recognize pointers to the interior of objects from conservatively scanned stack frames.  That's necessary because some compilers will construct part objects of larger objects with only a pointer to the part object in a register or on the stack.  If our allocation protocol could guarantee that the pointer to the object itself would be maintained somewhere we could avoid recognizing interior pointers, which would reduce false retention.  It's not clear what it would take to construct such a protocol, as it would have to be somewhat opaque to the optimizer to avoid a store being optimized away or reordered.

(RVCT is the one that came up, but we had some issues with StringIterator and MSVC that were papered over with the use of volatile, so the problem may be more general.)
(Reporter)

Updated

8 years ago
See Also: → bug 577118

Comment 2

8 years ago
Iron discipline will never happen, but iron enforcement via static analysis just might work.   Early versions of the avm didn't use conservative stack scanning and the rule was "you must pin your object with this API if your code can result in an allocation happening before your reference is written into the heap somewhere".    That was a tricky rule to follow.

One thing that could mitigate this whole issue pretty effectively is our ability to do GC work on the edges where we don't need to scan the stack at all.    We could beef up that up.   We could also tighten up the entry/exit code in the player, ie so that we enter/exit the GC multiple times per frame as we go through the various subsystems.   Of course AIR and background threads won't have the same setup as the player.

Comment 3

8 years ago
Any thoughts on how frame boundaries will be found?  the options I can think of are:

  a) unwind the stack using the platform stack conventions.  Some (PPC, ARM, maybe more) may require inspecting compiler-generated records to do this
  b) rely on MethodFrame locations and boundaries.  MF's form a linked list, but dont record the full bounds of the jit stack frame.  (they could).  this would divide the stack into known and unknown segments.  For JIT generated helpers we can also record enough data to support unwinding those frames.
(Reporter)

Updated

8 years ago
Target Milestone: --- → Future
(Reporter)

Updated

7 years ago
Blocks: 576307
No longer depends on: 576307
(Reporter)

Updated

7 years ago
Depends on: 604709, 604713
(Reporter)

Updated

7 years ago
Assignee: lhansen → nobody
Status: ASSIGNED → NEW
Whiteboard: Tracker

Updated

7 years ago
Whiteboard: Tracker → Tracking
(Reporter)

Updated

7 years ago
Priority: -- → P3
Target Milestone: Future → flash10.x-Serrano

Comment 4

7 years ago
Its worth noting that strict implementation of safegc would give us a way to track the lifetimes of stack pointers via the GCRef object.  Probably not useful for implementation purposes but might be good for "iron adherence" checking or data gathering.
(Reporter)

Updated

7 years ago
Target Milestone: Q3 11 - Serrano → Q1 12 - Brannan

Updated

7 years ago
Flags: flashplayer-qrb+
You need to log in before you can comment on or make changes to this bug.