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

Unified Diff: runtime/vm/parser.cc

Issue 18750004: Faster invocation of fields as methods. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 24991)
+++ runtime/vm/parser.cc (working copy)
@@ -776,6 +776,10 @@
node_sequence =
parser.ParseNoSuchMethodDispatcher(func, default_parameter_values);
break;
+ case RawFunction::kInvokeFieldDispatcher:
+ node_sequence =
+ parser.ParseInvokeFieldDispatcher(func, default_parameter_values);
+ break;
default:
UNREACHABLE();
}
@@ -1108,22 +1112,13 @@
}
-SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func,
- Array& default_values) {
- TRACE_PARSER("ParseNoSuchMethodDispatcher");
-
- ASSERT(func.IsNoSuchMethodDispatcher());
+void Parser::BuildDispatcherScope(const Function& func,
+ const ArgumentsDescriptor& desc,
+ Array& default_values) {
+ ParamList params;
+ // Receiver first.
intptr_t token_pos = func.token_pos();
- ASSERT(func.token_pos() == 0);
- ASSERT(current_class().raw() == func.Owner());
-
- ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc()));
- ASSERT(desc.Count() > 0);
-
- // Create parameter list. Receiver first.
- ParamList params;
params.AddReceiver(ReceiverType(), token_pos);
-
// Remaining positional parameters.
intptr_t i = 1;
for (; i < desc.PositionalCount(); ++i) {
@@ -1135,6 +1130,8 @@
params.parameters->Add(p);
params.num_fixed_parameters++;
}
+ ASSERT(desc.PositionalCount() == params.num_fixed_parameters);
+
// Named parameters.
for (; i < desc.Count(); ++i) {
ParamDesc p;
@@ -1146,23 +1143,40 @@
params.num_optional_parameters++;
params.has_optional_named_parameters = true;
}
+ ASSERT(desc.NamedCount() == params.num_optional_parameters);
SetupDefaultsForOptionalParams(&params, default_values);
// Build local scope for function and populate with the formal parameters.
OpenFunctionBlock(func);
- LocalScope* scope = current_block_->scope;
- AddFormalParamsToScope(&params, scope);
+ AddFormalParamsToScope(&params, current_block_->scope);
+}
+SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func,
+ Array& default_values) {
+ TRACE_PARSER("ParseNoSuchMethodDispatcher");
+
+ ASSERT(func.IsNoSuchMethodDispatcher());
+ intptr_t token_pos = func.token_pos();
+ ASSERT(func.token_pos() == 0);
+ ASSERT(current_class().raw() == func.Owner());
+
+ ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc()));
+ ASSERT(desc.Count() > 0);
+
+ // Set up scope for this function.
+ BuildDispatcherScope(func, desc, default_values);
+
// Receiver is local 0.
+ LocalScope* scope = current_block_->scope;
ArgumentListNode* func_args = new ArgumentListNode(token_pos);
for (intptr_t i = 0; i < desc.Count(); ++i) {
func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
}
- if (params.num_optional_parameters > 0) {
+ if (desc.NamedCount() > 0) {
const Array& arg_names =
- Array::ZoneHandle(Array::New(params.num_optional_parameters));
+ Array::ZoneHandle(Array::New(desc.NamedCount()));
for (intptr_t i = 0; i < arg_names.Length(); ++i) {
arg_names.SetAt(i, String::Handle(desc.NameAt(i)));
}
@@ -1186,6 +1200,62 @@
}
+SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func,
+ Array& default_values) {
+ TRACE_PARSER("ParseInvokeFieldDispatcher");
+
+ ASSERT(func.IsInvokeFieldDispatcher());
+ intptr_t token_pos = func.token_pos();
+ ASSERT(func.token_pos() == 0);
+ ASSERT(current_class().raw() == func.Owner());
+
+ const Array& args_desc = Array::Handle(func.saved_args_desc());
+ ArgumentsDescriptor desc(args_desc);
+ ASSERT(desc.Count() > 0);
+
+ // Set up scope for this function.
+ BuildDispatcherScope(func, desc, default_values);
+
+ // Receiver is local 0.
+ LocalScope* scope = current_block_->scope;
+ ArgumentListNode* no_args = new ArgumentListNode(token_pos);
+ LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0));
+
+ const String& name = String::Handle(func.name());
+ const String& getter_name =
+ String::ZoneHandle(Symbols::New(String::Handle(Field::GetterName(name))));
+ InstanceCallNode* getter_call = new InstanceCallNode(token_pos,
+ receiver,
+ getter_name,
+ no_args);
+
+ // Pass arguments 1..n to the closure call.
+ ArgumentListNode* closure_args = new ArgumentListNode(token_pos);
+ const Array& names = Array::Handle(Array::New(desc.NamedCount(), Heap::kOld));
+ // Positional parameters.
+ intptr_t i = 1;
+ for (; i < desc.PositionalCount(); ++i) {
+ closure_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
+ }
+ // Named parameters.
+ for (; i < desc.Count(); i++) {
+ closure_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
+ intptr_t index = i - desc.PositionalCount();
+ names.SetAt(index, String::Handle(desc.NameAt(index)));
+ }
+ closure_args->set_names(names);
+
+ EnsureSavedCurrentContext();
+ ClosureCallNode* closure_call = new ClosureCallNode(token_pos,
+ getter_call,
+ closure_args);
+
+ ReturnNode* return_node = new ReturnNode(token_pos, closure_call);
+ current_block_->statements->Add(return_node);
+ return CloseBlock();
+}
+
+
void Parser::SkipBlock() {
ASSERT(CurrentToken() == Token::kLBRACE);
GrowableArray<Token::Kind> token_stack(8);
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698