Closed Bug 891087 Opened 12 years ago Closed 12 years ago

getOperand and friends always called through vtable

Categories

(Core :: JavaScript Engine, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla25

People

(Reporter: sunfish, Unassigned)

References

Details

Attachments

(7 files, 6 obsolete files)

22.68 KB, patch
nbp
: review+
Details | Diff | Splinter Review
1.41 KB, patch
nbp
: review+
Details | Diff | Splinter Review
8.99 KB, patch
nbp
: review+
Details | Diff | Splinter Review
2.71 KB, patch
nbp
: review+
Details | Diff | Splinter Review
3.35 KB, patch
nbp
: review+
Details | Diff | Splinter Review
3.60 KB, patch
nbp
: review+
Details | Diff | Splinter Review
8.62 KB, patch
nbp
: review+
Details | Diff | Splinter Review
getOperand, numOperands, getSuccessor, numSuccessors, and several other related member functions in MNode and LInstruction are virtual, as they require subclass-specific implementations, however this leads to a significant number of unnecessary virtual calls. The following patch series significantly reduces the number of virtual calls in Ion and speeds up overall compile time on several benchmarks by a little under 2%.
The basic idea here is to rewrite for (unsigned i = 0; i < ins->numOperands(); i++) { to for (unsigned i = 0, e = ins->numOperands(); i < e; i++) { so that it makes one call instead of one per operand. This has the disadvantages of being slightly more fragile in the case where the node is modified while its operands are being visited, and it's a bit more to type, so I'm ok if you don't want to take this patch.
This doesn't actually eliminate any virtual calls; it's just a refactoring in the same area.
Attachment #772291 - Flags: review?
This patch implements manual devirtualization of MNode's getOperand, numOperands, setOperand, and getUseFor. With this patch, calls to these member functions from within subclasses make non-virtual calls rather than virtual calls. For example, MBinaryInstruction has an lhs() member function which returns getOperand(0). Despite the fact that lhs() knows its in an MBinaryInstruction which knows where its operands are, it currently still makes a virtual call. This patch fixes this. There are two obvious reasons why you may not want this patch. It introduces a fair amount of boilerplate code, which is (a) a little ugly, and (b) will be made obsolete when you can use the C++11 final keyword.
More manual devirtualization, similar to patch 772292.
In cases where the subclass is known, explicitly cast to the subclass before calling getOperand or similar. This allows the call to be devirtualized with the help of patch 772292. It would also work with the C++-11 final keyword.
This patch is similar to 772295, but it introduces casts for MBinaryInstruction and related classes which are not most-derived classes and don't have toFoo()-style checked cast functions. It uses static_cast, which is unchecked. However, the code is fairly easy to check manually.
This patch implements the same kind of change as patch 772292 for LInstruction's operands, successors, defs, and temps.
Comment on attachment 772289 [details] [diff] [review] reduce numOperands calls Review of attachment 772289 [details] [diff] [review]: ----------------------------------------------------------------- That would be nice if we could instruct the compiler to do this lifting auto-magically, one way would be to have a constant MDefinition / MResumePoints when we iterate over the set of operands, in which case this lifting should be done by the compiler. Another way would be to have an accessor on MNode which wrap numOperands with an __attribute__(pure), as long as the compiler does not create a persistent table of entries. In which case this will not work with futher mutations. Do you want me to review your patches?
Attachment #772289 - Flags: feedback+
Attachment #772292 - Attachment is obsolete: true
Attachment #772293 - Attachment is obsolete: true
Comment on attachment 772321 [details] [diff] [review] devirtualize LInstruction's getOperand and friends Someone on IRC pointed me to the MOZ_FINAL macro, which provides access to the C++11 final keyword in a portable way, and indicated that most compilers would be supporting it in one way or another soon enough, so that seems like a better approach than these three boilerplate patches. I plan to submit a MOZ_FINAL patch to replace these.
Attachment #772321 - Attachment is obsolete: true
Attachment #772289 - Flags: review?(nicolas.b.pierron)
Attachment #772290 - Flags: review?(nicolas.b.pierron)
Attachment #772291 - Flags: review? → review?(nicolas.b.pierron)
Attachment #772295 - Flags: review?(nicolas.b.pierron)
Attachment #772298 - Flags: review?(nicolas.b.pierron)
Attachment #772911 - Flags: review?(nicolas.b.pierron)
Attachment #772912 - Flags: review?(nicolas.b.pierron)
Attachment #772913 - Flags: review?(nicolas.b.pierron)
Attachment #772289 - Flags: review?(nicolas.b.pierron) → review+
Attachment #772290 - Flags: review?(nicolas.b.pierron) → review+
Attachment #772291 - Flags: review?(nicolas.b.pierron) → review+
Attachment #772295 - Flags: review?(nicolas.b.pierron) → review+
Attachment #772298 - Flags: review?(nicolas.b.pierron) → review+
Attachment #772911 - Flags: review?(nicolas.b.pierron) → review+
Attachment #772912 - Flags: review?(nicolas.b.pierron) → review+
Comment on attachment 772913 [details] [diff] [review] add MOZ_FINAL to LInstruction's operand, def, temp, and successor accessors Review of attachment 772913 [details] [diff] [review]: ----------------------------------------------------------------- ::: js/src/ion/LIR-Common.h @@ +4483,5 @@ > LIR_HEADER(Phi) > > static LPhi *New(MIRGenerator *gen, MPhi *phi); > > + size_t numDefs() const MOZ_FINAL MOZ_OVERRIDE { Move the MOZ_FINAL to the class definition. We should probably do the same thing for MPhi.
Attachment #772913 - Flags: review?(nicolas.b.pierron)
Good idea. This patch adds MOZ_FINAL to MPhi, LPhi, and a few other pertinent ones.
Attachment #772911 - Attachment is obsolete: true
Attachment #772912 - Attachment is obsolete: true
Attachment #772913 - Attachment is obsolete: true
Attachment #773052 - Flags: review?(nicolas.b.pierron)
This patch covers all the remaining MOZ_FINAL attributes on member functions, because they are in classes which can't be marked MOZ_FINAL.
Attachment #773054 - Flags: review?(nicolas.b.pierron)
Attachment #773052 - Flags: review?(nicolas.b.pierron) → review+
Comment on attachment 773054 [details] [diff] [review] the remaining member-function MOZ_FINALs Review of attachment 773054 [details] [diff] [review]: ----------------------------------------------------------------- ::: js/src/ion/LIR-Common.h @@ +227,5 @@ > > public: > + size_t numSuccessors() const MOZ_FINAL MOZ_OVERRIDE { return Succs; } > + > + MBasicBlock *getSuccessor(size_t i) const MOZ_FINAL MOZ_OVERRIDE { return successors_[i]; } style nit: This might look nicer with new lines. ;)
Attachment #773054 - Flags: review?(nicolas.b.pierron) → review+
Comment on attachment 773054 [details] [diff] [review] the remaining member-function MOZ_FINALs Review of attachment 773054 [details] [diff] [review]: ----------------------------------------------------------------- ::: js/src/ion/LIR-Common.h @@ +225,5 @@ > > MBasicBlock *successors_[Succs]; > > public: > + size_t numSuccessors() const MOZ_FINAL MOZ_OVERRIDE { return Succs; } mrbkap, notice that these functions are not virtual function, in which case these 2 keywords are causing error messages with clang 4.0. 0:18.32 /Users/mrbkap/work/clean/mozilla/js/src/ion/LIR-Common.h:229:5: error: only virtual member functions can be marked 'override' 0:18.32 size_t numSuccessors() const MOZ_FINAL MOZ_OVERRIDE { return Succs; } 0:18.32 ^ ~~~~~~~~~~~~ 0:18.32 /Users/mrbkap/work/clean/mozilla/js/src/ion/LIR-Common.h:229:5: error: only virtual member functions can be marked 'final' 0:18.32 size_t numSuccessors() const MOZ_FINAL MOZ_OVERRIDE { return Succs; }
numSuccessors() is a virtual member function in the base class LInstruction, so it should be implicitly virtual in the derived classes. Is this version of clang requiring an explicit "virtual" keyword here? Also, there is no clang 4.0 yet.
Depends on: 892594
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: