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

Unified Diff: runtime/vm/flow_graph_builder.cc

Issue 22839003: Polymorphic inlining for some recognized methods in the optimizing compiler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: fixed modulo performance regression Created 7 years, 4 months 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/compiler.cc ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_builder.cc
===================================================================
--- runtime/vm/flow_graph_builder.cc (revision 26420)
+++ runtime/vm/flow_graph_builder.cc (working copy)
@@ -2850,8 +2850,74 @@
}
+static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) {
+ switch (kind) {
+ case MethodRecognizer::kObjectArrayLength:
+ case MethodRecognizer::kImmutableArrayLength:
+ return Array::length_offset();
+ case MethodRecognizer::kTypedDataLength:
+ // .length is defined in _TypedList which is the base class for internal
+ // and external typed data.
+ ASSERT(TypedData::length_offset() == ExternalTypedData::length_offset());
+ return TypedData::length_offset();
+ case MethodRecognizer::kGrowableArrayLength:
+ return GrowableObjectArray::length_offset();
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+
void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
+ const Function& function = owner()->parsed_function()->function();
+ if (!function.IsClosureFunction()) {
+ MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
+ switch (kind) {
+ case MethodRecognizer::kStringBaseLength: {
+ LocalVariable* receiver_var =
+ node->scope()->LookupVariable(Symbols::This(),
+ true); // Test only.
+ Value* receiver = Bind(new LoadLocalInstr(*receiver_var));
+ // Treat length loads as mutable (i.e. affected by side effects) to
+ // avoid hoisting them since we can't hoist the preceding class-check.
+ // This is because of externalization of strings that affects their
+ // class-id.
+ const bool is_immutable = false;
+ LoadFieldInstr* load = new LoadFieldInstr(
+ receiver,
+ String::length_offset(),
+ Type::ZoneHandle(Type::SmiType()),
+ is_immutable);
+ load->set_result_cid(kSmiCid);
+ load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
+ return ReturnDefinition(load);
+ }
+ case MethodRecognizer::kGrowableArrayLength:
+ case MethodRecognizer::kObjectArrayLength:
+ case MethodRecognizer::kImmutableArrayLength:
+ case MethodRecognizer::kTypedDataLength: {
+ LocalVariable* receiver_var =
+ node->scope()->LookupVariable(Symbols::This(),
+ true); // Test only.
+ Value* receiver = Bind(new LoadLocalInstr(*receiver_var));
+ const bool is_immutable =
+ (kind != MethodRecognizer::kGrowableArrayLength);
+ LoadFieldInstr* load = new LoadFieldInstr(
+ receiver,
+ OffsetForLengthGetter(kind),
+ Type::ZoneHandle(Type::SmiType()),
+ is_immutable);
+ load->set_result_cid(kSmiCid);
+ load->set_recognized_kind(kind);
+ return ReturnDefinition(load);
+ }
+ default:
+ break;
+ }
+ }
InlineBailout("EffectGraphVisitor::VisitNativeBodyNode");
+ function.set_is_optimizable(false);
NativeCallInstr* native_call = new NativeCallInstr(node);
ReturnDefinition(native_call);
}
@@ -3210,10 +3276,8 @@
// memory leaks.
// In this case, the parser pre-allocates a variable to save the context.
if (MustSaveRestoreContext(node)) {
- Value* current_context = Bind(new CurrentContextInstr());
- Do(BuildStoreTemp(
- *owner()->parsed_function()->saved_entry_context_var(),
- current_context));
+ BuildSaveContext(
+ *owner()->parsed_function()->saved_entry_context_var());
Value* null_context = Bind(new ConstantInstr(Object::ZoneHandle()));
AddInstruction(new StoreContextInstr(null_context));
}
@@ -3630,11 +3694,14 @@
graph_entry_ = new GraphEntryInstr(*parsed_function(), normal_entry, osr_id_);
EffectGraphVisitor for_effect(this, 0);
// This check may be deleted if the generated code is leaf.
- CheckStackOverflowInstr* check =
- new CheckStackOverflowInstr(function.token_pos(), 0);
- // If we are inlining don't actually attach the stack check. We must still
- // create the stack check in order to allocate a deopt id.
- if (!IsInlining()) for_effect.AddInstruction(check);
+ // Native functions don't need a stack check at entry.
+ if (!function.is_native()) {
+ CheckStackOverflowInstr* check =
+ new CheckStackOverflowInstr(function.token_pos(), 0);
+ // If we are inlining don't actually attach the stack check. We must still
+ // create the stack check in order to allocate a deopt id.
+ if (!IsInlining()) for_effect.AddInstruction(check);
+ }
parsed_function()->node_sequence()->Visit(&for_effect);
AppendFragment(normal_entry, for_effect);
// Check that the graph is properly terminated.
« no previous file with comments | « runtime/vm/compiler.cc ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698