Emit switchable instance calls when we don't know the complete set of receiver classes for a call site.

A switchable call in the monomorphic state is now basically the same cost as a test and call, so this is as performant without ht code size cost of the slow path megemorphic call.

Flutter gallery before:
VMIsolate(CodeSize): 114052
Isolate(CodeSize): 2250283
ReadOnlyData(CodeSize): 1744760
Instructions(CodeSize): 5679488
Total(CodeSize): 9788583

After:
VMIsolate(CodeSize): 114085
Isolate(CodeSize): 2047224
ReadOnlyData(CodeSize): 1666808
Instructions(CodeSize): 5405424 -4.8%
Total(CodeSize): 9233541  -5.6%

R=fschneider@google.com

Review URL: https://codereview.chromium.org/2376893003 .
This commit is contained in:
Ryan Macnak 2016-09-30 17:34:39 -07:00
parent 6cff17c59a
commit 271483911f
8 changed files with 2 additions and 110 deletions

View file

@ -1914,20 +1914,8 @@ void FlowGraphCompiler::EmitPolymorphicInstanceCall(
deopt_id, token_pos, locs, true);
assembler()->Bind(&ok);
} else {
// Instead of deoptimizing, do a megamorphic call when no matching
// cid found.
Label ok;
MegamorphicSlowPath* slow_path =
new MegamorphicSlowPath(ic_data, argument_count, deopt_id,
token_pos, locs, CurrentTryIndex());
AddSlowPathCode(slow_path);
EmitTestAndCall(ic_data, argument_count, argument_names,
slow_path->entry_label(), // No cid match.
&ok, // Found cid.
deopt_id, token_pos, locs, false);
assembler()->Bind(slow_path->exit_label());
assembler()->Bind(&ok);
EmitSwitchableInstanceCall(ic_data, argument_count,
deopt_id, token_pos, locs);
}
}
}

View file

@ -213,37 +213,6 @@ class SlowPathCode : public ZoneAllocated {
};
class MegamorphicSlowPath : public SlowPathCode {
public:
MegamorphicSlowPath(const ICData& ic_data,
intptr_t argument_count,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
intptr_t try_index)
: SlowPathCode(),
ic_data_(ic_data),
argument_count_(argument_count),
deopt_id_(deopt_id),
token_pos_(token_pos),
locs_(locs),
try_index_(try_index) {}
virtual ~MegamorphicSlowPath() {}
private:
virtual void EmitNativeCode(FlowGraphCompiler* comp);
const ICData& ic_data_;
intptr_t argument_count_;
intptr_t deopt_id_;
TokenPosition token_pos_;
LocationSummary* locs_;
const intptr_t try_index_; // For try/catch ranges.
DISALLOW_COPY_AND_ASSIGN(MegamorphicSlowPath);
};
struct CidTarget {
intptr_t cid;
Function* target;

View file

@ -29,18 +29,6 @@ DEFINE_FLAG(bool, unbox_doubles, true, "Optimize double arithmetic.");
DECLARE_FLAG(bool, enable_simd_inline);
void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
Assembler* assembler = compiler->assembler();
#define __ assembler->
__ Bind(entry_label());
__ Comment("MegamorphicSlowPath");
compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
token_pos_, locs_, try_index_);
__ b(exit_label());
#undef __
}
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.

View file

@ -27,18 +27,6 @@ DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
DECLARE_FLAG(bool, enable_simd_inline);
void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
Assembler* assembler = compiler->assembler();
#define __ assembler->
__ Bind(entry_label());
__ Comment("MegamorphicSlowPath");
compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
token_pos_, locs_, try_index_);
__ b(exit_label());
#undef __
}
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.

View file

@ -29,11 +29,6 @@ DEFINE_FLAG(bool, unbox_doubles, true, "Optimize double arithmetic.");
DECLARE_FLAG(bool, enable_simd_inline);
DECLARE_FLAG(charp, optimization_filter);
void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
UNIMPLEMENTED();
}
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.

View file

@ -31,18 +31,6 @@ DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
DECLARE_FLAG(bool, enable_simd_inline);
void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
Assembler* assembler = compiler->assembler();
#define __ assembler->
__ Bind(entry_label());
__ Comment("MegamorphicSlowPath");
compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
token_pos_, locs_, try_index_);
__ jmp(exit_label());
#undef __
}
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.

View file

@ -25,18 +25,6 @@ namespace dart {
DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
Assembler* assembler = compiler->assembler();
#define __ assembler->
__ Bind(entry_label());
__ Comment("MegamorphicSlowPath");
compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
token_pos_, locs_, try_index_);
__ b(exit_label());
#undef __
}
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.

View file

@ -27,18 +27,6 @@ DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
DECLARE_FLAG(bool, enable_simd_inline);
void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
Assembler* assembler = compiler->assembler();
#define __ assembler->
__ Bind(entry_label());
__ Comment("MegamorphicSlowPath");
compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
token_pos_, locs_, try_index_);
__ jmp(exit_label());
#undef __
}
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.