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

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: 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
Index: runtime/vm/flow_graph_builder.cc
===================================================================
--- runtime/vm/flow_graph_builder.cc (revision 25997)
+++ runtime/vm/flow_graph_builder.cc (working copy)
@@ -2808,8 +2808,75 @@
}
+static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) {
srdjan 2013/08/12 21:49:47 Can we share this with the one in FlowGraphOptimiz
Florian Schneider 2013/08/14 12:30:24 The one in the FlowGraphOptimizer is gone with thi
+ 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);
Kevin Millikin (Google) 2013/08/13 11:47:40 Fits on the previous line.
Florian Schneider 2013/08/14 12:30:24 Done.
+ 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);
}
@@ -3168,10 +3235,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(
Florian Schneider 2013/08/12 15:48:14 Unrelated refactoring.
+ *owner()->parsed_function()->saved_entry_context_var());
Value* null_context = Bind(new ConstantInstr(Object::ZoneHandle()));
AddInstruction(new StoreContextInstr(null_context));
}
@@ -3586,11 +3651,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.

Powered by Google App Engine
This is Rietveld 408576698