Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(576)

Unified Diff: runtime/vm/stub_code_x64.cc

Issue 11361225: In optimized code use IC calls for instance calls that have no IC data instead of deoptimizing. The… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/stub_code_x64.cc
===================================================================
--- runtime/vm/stub_code_x64.cc (revision 14858)
+++ runtime/vm/stub_code_x64.cc (working copy)
@@ -25,6 +25,7 @@
DEFINE_FLAG(bool, use_slow_path, false,
"Set to true for debugging & verifying the slow paths.");
DECLARE_FLAG(int, optimization_counter_threshold);
+DECLARE_FLAG(bool, trace_optimized_ic_calls);
// Input parameters:
// RSP : points to return address.
@@ -1504,24 +1505,60 @@
}
+void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
+ Register argdesc_reg = R10;
+ Register ic_reg = RBX;
+ Register func_reg = RDI;
+ if (FLAG_trace_optimized_ic_calls) {
+ AssemblerMacros::EnterStubFrame(assembler);
+ __ pushq(func_reg); // Preserve
+ __ pushq(argdesc_reg); // Preserve.
+ __ pushq(ic_reg); // Preserve.
+ __ pushq(ic_reg); // Argument.
+ __ pushq(func_reg); // Argument.
+ __ CallRuntime(kTraceICCallRuntimeEntry);
+ __ popq(RAX); // Discard argument;
+ __ popq(RAX); // Discard argument;
+ __ popq(ic_reg); // Restore.
+ __ popq(argdesc_reg); // Restore.
+ __ popq(func_reg); // Restore.
+ __ LeaveFrame();
+ }
+ Label is_hot;
+ if (FlowGraphCompiler::CanOptimize()) {
+ ASSERT(FLAG_optimization_counter_threshold > 1);
+ __ cmpq(FieldAddress(func_reg, Function::usage_counter_offset()),
+ Immediate(FLAG_optimization_counter_threshold));
+ __ j(GREATER_EQUAL, &is_hot, Assembler::kNearJump);
+ // As long as VM has no OSR do not optimize in the middle of the function
+ // but only at exit so that we have collected all type feedback before
+ // optimizing.
+ }
+ __ incq(FieldAddress(func_reg, Function::usage_counter_offset()));
+ __ Bind(&is_hot);
+}
+
+
// Loads function into 'temp_reg', preserves 'ic_reg'.
void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
- Register ic_reg,
Register temp_reg) {
- __ movq(temp_reg, FieldAddress(ic_reg, ICData::function_offset()));
+ Register ic_reg = RBX;
+ Register func_reg = temp_reg;
+ ASSERT(ic_reg != func_reg);
+ __ movq(func_reg, FieldAddress(ic_reg, ICData::function_offset()));
Label is_hot;
if (FlowGraphCompiler::CanOptimize()) {
ASSERT(FLAG_optimization_counter_threshold > 1);
// The usage_counter is always less than FLAG_optimization_counter_threshold
// except when the function gets optimized.
- __ cmpq(FieldAddress(temp_reg, Function::usage_counter_offset()),
+ __ cmpq(FieldAddress(func_reg, Function::usage_counter_offset()),
Immediate(FLAG_optimization_counter_threshold));
__ j(EQUAL, &is_hot, Assembler::kNearJump);
// As long as VM has no OSR do not optimize in the middle of the function
// but only at exit so that we have collected all type feedback before
// optimizing.
}
- __ incq(FieldAddress(temp_reg, Function::usage_counter_offset()));
+ __ incq(FieldAddress(func_reg, Function::usage_counter_offset()));
__ Bind(&is_hot);
}
@@ -1640,6 +1677,9 @@
__ cmpq(RAX, raw_null);
__ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump);
// NoSuchMethod or closure.
+ // Mark IC call that it may be a closure call that does not collect
+ // type feedback.
+ __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1));
__ jmp(&StubCode::InstanceFunctionLookupLabel());
__ Bind(&found);
@@ -1680,26 +1720,65 @@
// - N classes.
// - 1 target function.
void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
- GenerateUsageCounterIncrement(assembler, RBX, RCX);
- return GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateUsageCounterIncrement(assembler, RCX);
+ GenerateNArgsCheckInlineCacheStub(assembler, 1);
}
void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
- GenerateUsageCounterIncrement(assembler, RBX, RCX);
- return GenerateNArgsCheckInlineCacheStub(assembler, 2);
+ GenerateUsageCounterIncrement(assembler, RCX);
+ GenerateNArgsCheckInlineCacheStub(assembler, 2);
}
void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
- GenerateUsageCounterIncrement(assembler, RBX, RCX);
- return GenerateNArgsCheckInlineCacheStub(assembler, 3);
+ GenerateUsageCounterIncrement(assembler, RCX);
+ GenerateNArgsCheckInlineCacheStub(assembler, 3);
}
+// Use inline cache data array to invoke the target or continue in inline
+// cache miss handler. Stub for 1-argument check (receiver class).
+// RDI: function which counter needs to be incremented.
+// RBX: Inline cache data object.
+// RDX: Arguments array.
+// TOS(0): Return address.
+// Inline cache data object structure:
+// 0: function-name
+// 1: N, number of arguments checked.
+// 2 .. (length - 1): group of checks, each check containing:
+// - N classes.
+// - 1 target function.
+void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
+ Assembler* assembler) {
+ GenerateOptimizedUsageCounterIncrement(assembler);
+ GenerateNArgsCheckInlineCacheStub(assembler, 1);
+}
+
+
+void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
+ Assembler* assembler) {
+ GenerateOptimizedUsageCounterIncrement(assembler);
+ GenerateNArgsCheckInlineCacheStub(assembler, 2);
+}
+
+
+void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
+ Assembler* assembler) {
+ GenerateOptimizedUsageCounterIncrement(assembler);
+ GenerateNArgsCheckInlineCacheStub(assembler, 3);
+}
+
+
+// Do not count as no type feedback is collected.
+void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
+ GenerateNArgsCheckInlineCacheStub(assembler, 1);
+}
+
+
// Megamorphic call is currently implemented as IC call but through a stub
// that does not check/count function invocations.
void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
- return GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(assembler, 1);
}
// RBX: Function object.
« no previous file with comments | « runtime/vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698