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

Side by Side Diff: runtime/vm/code_generator.cc

Issue 17315008: Optimizing noSuchMethod invocation with no arguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/debugger.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 #include "vm/ast.h" 8 #include "vm/ast.h"
9 #include "vm/bigint_operations.h" 9 #include "vm/bigint_operations.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 const Array& args_descriptor_array) { 874 const Array& args_descriptor_array) {
875 const Instance& receiver = *args[0]; 875 const Instance& receiver = *args[0];
876 const Code& target_code = 876 const Code& target_code =
877 Code::Handle(ResolveCompileInstanceCallTarget(receiver, 877 Code::Handle(ResolveCompileInstanceCallTarget(receiver,
878 ic_data, 878 ic_data,
879 args_descriptor_array)); 879 args_descriptor_array));
880 if (target_code.IsNull()) { 880 if (target_code.IsNull()) {
881 // Let the megamorphic stub handle special cases: NoSuchMethod, 881 // Let the megamorphic stub handle special cases: NoSuchMethod,
882 // closure calls. 882 // closure calls.
883 if (FLAG_trace_ic) { 883 if (FLAG_trace_ic) {
884 OS::PrintErr("InlineCacheMissHandler NULL code for receiver: %s\n", 884 OS::PrintErr("InlineCacheMissHandler NULL code for %s receiver: %s\n",
885 receiver.ToCString()); 885 String::Handle(ic_data.target_name()).ToCString(),
886 receiver.ToCString());
886 } 887 }
887 return Function::null(); 888 return Function::null();
888 } 889 }
889 const Function& target_function = 890 const Function& target_function =
890 Function::Handle(target_code.function()); 891 Function::Handle(target_code.function());
891 ASSERT(!target_function.IsNull()); 892 ASSERT(!target_function.IsNull());
892 if (args.length() == 1) { 893 if (args.length() == 1) {
893 ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function); 894 ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function);
894 } else { 895 } else {
895 GrowableArray<intptr_t> class_ids(args.length()); 896 GrowableArray<intptr_t> class_ids(args.length());
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1150 Object* result) { 1151 Object* result) {
1151 // 1. Check if there is a getter with the same name. 1152 // 1. Check if there is a getter with the same name.
1152 const String& getter_name = String::Handle(Field::GetterName(target_name)); 1153 const String& getter_name = String::Handle(Field::GetterName(target_name));
1153 const int kNumArguments = 1; 1154 const int kNumArguments = 1;
1154 const int kNumNamedArguments = 0; 1155 const int kNumNamedArguments = 0;
1155 const Function& getter = Function::Handle( 1156 const Function& getter = Function::Handle(
1156 Resolver::ResolveDynamicForReceiverClass(receiver_class, 1157 Resolver::ResolveDynamicForReceiverClass(receiver_class,
1157 getter_name, 1158 getter_name,
1158 kNumArguments, 1159 kNumArguments,
1159 kNumNamedArguments)); 1160 kNumNamedArguments));
1160 if (getter.IsNull() || getter.IsMethodExtractor()) { 1161 if (getter.IsNull() ||
1162 getter.IsMethodExtractor() ||
1163 getter.IsNoSuchMethodDispatcher()) {
1161 return false; 1164 return false;
1162 } 1165 }
1163 1166
1164 // 2. Invoke the getter. 1167 // 2. Invoke the getter.
1165 const Array& args = Array::Handle(Array::New(kNumArguments)); 1168 const Array& args = Array::Handle(Array::New(kNumArguments));
1166 args.SetAt(0, receiver); 1169 args.SetAt(0, receiver);
1167 const Object& value = Object::Handle(DartEntry::InvokeFunction(getter, args)); 1170 const Object& value = Object::Handle(DartEntry::InvokeFunction(getter, args));
1168 1171
1169 // 3. If the getter threw an exception, treat it as no such method. 1172 // 3. If the getter threw an exception, treat it as no such method.
1170 if (value.IsUnhandledException()) return false; 1173 if (value.IsUnhandledException()) return false;
1171 1174
1172 // 4. If there was some other error, propagate it. 1175 // 4. If there was some other error, propagate it.
1173 CheckResultError(value); 1176 CheckResultError(value);
1174 1177
1175 // 5. Invoke the value as a closure. 1178 // 5. Invoke the value as a closure.
1176 Instance& instance = Instance::Handle(); 1179 Instance& instance = Instance::Handle();
1177 instance ^= value.raw(); 1180 instance ^= value.raw();
1178 arguments.SetAt(0, instance); 1181 arguments.SetAt(0, instance);
1179 *result = DartEntry::InvokeClosure(arguments, arguments_descriptor); 1182 *result = DartEntry::InvokeClosure(arguments, arguments_descriptor);
1180 CheckResultError(*result); 1183 CheckResultError(*result);
1181 return true; 1184 return true;
1182 } 1185 }
1183 1186
1184 1187
1188 // Create a method for noSuchMethod invocation and attach it to the receiver
1189 // class.
1190 static RawFunction* CreateNoSuchMethodDispatcher(
1191 const String& target_name,
1192 const Class& receiver_class,
1193 const Array& arguments_descriptor) {
1194 Function& invocation = Function::Handle(
1195 Function::New(String::Handle(Symbols::New(target_name)),
1196 RawFunction::kNoSuchMethodDispatcher,
1197 false, // Not static.
1198 false, // Not const.
1199 false, // Not abstract.
1200 false, // Not external.
1201 receiver_class,
1202 0)); // No token position.
1203
1204 // Initialize signature: receiver is a single fixed parameter.
1205 const intptr_t kNumParameters = 1;
1206 invocation.set_num_fixed_parameters(kNumParameters);
1207 invocation.SetNumOptionalParameters(0, 0);
1208 invocation.set_parameter_types(Array::Handle(Array::New(kNumParameters,
1209 Heap::kOld)));
1210 invocation.set_parameter_names(Array::Handle(Array::New(kNumParameters,
1211 Heap::kOld)));
1212 invocation.SetParameterTypeAt(0, Type::Handle(Type::DynamicType()));
1213 invocation.SetParameterNameAt(0, Symbols::This());
1214 invocation.set_result_type(Type::Handle(Type::DynamicType()));
1215 invocation.set_is_visible(false); // Not visible in stack trace.
1216
1217 receiver_class.AddFunction(invocation);
1218
1219 return invocation.raw();
1220 }
1221
1222
1185 // The IC miss handler has failed to find a (cacheable) instance function to 1223 // The IC miss handler has failed to find a (cacheable) instance function to
1186 // invoke. Handle three possibilities: 1224 // invoke. Handle three possibilities:
1187 // 1225 //
1188 // 1. If the call was a getter o.f, there may be an instance function with 1226 // 1. If the call was a getter o.f, there may be an instance function with
1189 // the same name. If so, create an implicit closure and return it. 1227 // the same name. If so, create an implicit closure and return it.
1190 // 1228 //
1191 // 2. If the call was an instance call o.f(...), there may be a getter with 1229 // 2. If the call was an instance call o.f(...), there may be a getter with
1192 // the same name. If so, invoke it. If the value is a closure, invoke 1230 // the same name. If so, invoke it. If the value is a closure, invoke
1193 // it with the given arguments. If the value is a non-closure, attempt 1231 // it with the given arguments. If the value is a non-closure, attempt
1194 // to invoke "call" on it. 1232 // to invoke "call" on it.
(...skipping 14 matching lines...) Expand all
1209 } 1247 }
1210 const String& target_name = String::Handle(ic_data.target_name()); 1248 const String& target_name = String::Handle(ic_data.target_name());
1211 1249
1212 Object& result = Object::Handle(); 1250 Object& result = Object::Handle();
1213 if (!ResolveCallThroughGetter(receiver, 1251 if (!ResolveCallThroughGetter(receiver,
1214 receiver_class, 1252 receiver_class,
1215 target_name, 1253 target_name,
1216 args_descriptor, 1254 args_descriptor,
1217 args, 1255 args,
1218 &result)) { 1256 &result)) {
1219 result = DartEntry::InvokeNoSuchMethod(receiver, 1257 ArgumentsDescriptor desc(args_descriptor);
1220 target_name, 1258 // TODO(fschneider): Handle multiple arguments.
1221 args, 1259 if ((desc.Count() == 1) && (desc.PositionalCount() == 1)) {
1222 args_descriptor); 1260 // Create Function for noSuchMethodInvocation and add it to the class.
1261 Function& target_function = Function::Handle();
1262 target_function ^= CreateNoSuchMethodDispatcher(target_name,
1263 receiver_class,
1264 args_descriptor);
1265
1266 // Update IC data.
1267 ASSERT(!target_function.IsNull());
1268 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
1269 if (FLAG_trace_ic) {
1270 OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%"Pd" -> <%s>\n",
1271 Class::Handle(receiver.clazz()).ToCString(),
1272 receiver.GetClassId(),
1273 target_function.ToCString());
1274 }
1275 result =
1276 DartEntry::InvokeFunction(target_function, args, args_descriptor);
1277 } else {
1278 result = DartEntry::InvokeNoSuchMethod(receiver,
1279 target_name,
1280 args,
1281 args_descriptor);
1282 }
1223 } 1283 }
1224 CheckResultError(result); 1284 CheckResultError(result);
1225 arguments.SetReturn(result); 1285 arguments.SetReturn(result);
1226 } 1286 }
1227 1287
1228 1288
1229 static bool CanOptimizeFunction(const Function& function, Isolate* isolate) { 1289 static bool CanOptimizeFunction(const Function& function, Isolate* isolate) {
1230 const intptr_t kLowInvocationCount = -100000000; 1290 const intptr_t kLowInvocationCount = -100000000;
1231 if (isolate->debugger()->HasBreakpoint(function)) { 1291 if (isolate->debugger()->HasBreakpoint(function)) {
1232 // We cannot set breakpoints in optimized code, so do not optimize 1292 // We cannot set breakpoints in optimized code, so do not optimize
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 // Arg1: Value that is being stored. 1866 // Arg1: Value that is being stored.
1807 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { 1867 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) {
1808 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); 1868 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count());
1809 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); 1869 const Field& field = Field::CheckedHandle(arguments.ArgAt(0));
1810 const Object& value = Object::Handle(arguments.ArgAt(1)); 1870 const Object& value = Object::Handle(arguments.ArgAt(1));
1811 1871
1812 field.UpdateCid(value.GetClassId()); 1872 field.UpdateCid(value.GetClassId());
1813 } 1873 }
1814 1874
1815 } // namespace dart 1875 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/debugger.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698