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

Side by Side Diff: runtime/vm/code_generator.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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/debugger.h » ('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 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 1177
1178 // An instance call of the form o.f(...) could not be resolved. Check if 1178 // An instance call of the form o.f(...) could not be resolved. Check if
1179 // there is a getter with the same name. If so, invoke it. If the value is 1179 // there is a getter with the same name. If so, invoke it. If the value is
1180 // a closure, invoke it with the given arguments. If the value is a 1180 // a closure, invoke it with the given arguments. If the value is a
1181 // non-closure, attempt to invoke "call" on it. 1181 // non-closure, attempt to invoke "call" on it.
1182 static bool ResolveCallThroughGetter(const Instance& receiver, 1182 static bool ResolveCallThroughGetter(const Instance& receiver,
1183 const Class& receiver_class, 1183 const Class& receiver_class,
1184 const String& target_name, 1184 const String& target_name,
1185 const Array& arguments_descriptor, 1185 const Array& arguments_descriptor,
1186 const Array& arguments, 1186 const Array& arguments,
1187 const ICData& ic_data,
1187 Object* result) { 1188 Object* result) {
1188 // 1. Check if there is a getter with the same name. 1189 // 1. Check if there is a getter with the same name.
1189 const String& getter_name = String::Handle(Field::GetterName(target_name)); 1190 const String& getter_name = String::Handle(Field::GetterName(target_name));
1190 const int kNumArguments = 1; 1191 const int kNumArguments = 1;
1191 const int kNumNamedArguments = 0; 1192 const int kNumNamedArguments = 0;
1192 const Function& getter = Function::Handle( 1193 const Function& getter = Function::Handle(
1193 Resolver::ResolveDynamicForReceiverClass(receiver_class, 1194 Resolver::ResolveDynamicForReceiverClass(receiver_class,
1194 getter_name, 1195 getter_name,
1195 kNumArguments, 1196 kNumArguments,
1196 kNumNamedArguments)); 1197 kNumNamedArguments));
1197 if (getter.IsNull() || getter.IsMethodExtractor()) { 1198 if (getter.IsNull() || getter.IsMethodExtractor()) {
1198 return false; 1199 return false;
1199 } 1200 }
1200 1201
1201 // 2. Invoke the getter. 1202 const Function& target_function =
1202 const Array& args = Array::Handle(Array::New(kNumArguments)); 1203 Function::Handle(receiver_class.GetInvocationDispatcher(
1203 args.SetAt(0, receiver); 1204 target_name,
1204 const Object& value = Object::Handle(DartEntry::InvokeFunction(getter, args)); 1205 arguments_descriptor,
1205 1206 RawFunction::kInvokeFieldDispatcher));
1206 // 3. If there was some error, propagate it. 1207 // Update IC data.
1207 CheckResultError(value); 1208 ASSERT(!target_function.IsNull());
1208 1209 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
1209 // 4. Invoke the value as a closure. 1210 if (FLAG_trace_ic) {
1210 Instance& instance = Instance::Handle(); 1211 OS::PrintErr("InvokeField IC miss: adding <%s> id:%"Pd" -> <%s>\n",
1211 instance ^= value.raw(); 1212 Class::Handle(receiver.clazz()).ToCString(),
1212 arguments.SetAt(0, instance); 1213 receiver.GetClassId(),
1213 *result = DartEntry::InvokeClosure(arguments, arguments_descriptor); 1214 target_function.ToCString());
1215 }
1216 *result = DartEntry::InvokeFunction(target_function,
1217 arguments,
1218 arguments_descriptor);
1214 CheckResultError(*result); 1219 CheckResultError(*result);
1215 return true; 1220 return true;
1216 } 1221 }
1217 1222
1218 1223
1219 // The IC miss handler has failed to find a (cacheable) instance function to 1224 // The IC miss handler has failed to find a (cacheable) instance function to
1220 // invoke. Handle three possibilities: 1225 // invoke. Handle three possibilities:
1221 // 1226 //
1222 // 1. If the call was a getter o.f, there may be an instance function with 1227 // 1. If the call was a getter o.f, there may be an instance function with
1223 // the same name. If so, create an implicit closure and return it. 1228 // the same name. If so, create an implicit closure and return it.
(...skipping 18 matching lines...) Expand all
1242 receiver_class = isolate->object_store()->object_class(); 1247 receiver_class = isolate->object_store()->object_class();
1243 } 1248 }
1244 const String& target_name = String::Handle(ic_data.target_name()); 1249 const String& target_name = String::Handle(ic_data.target_name());
1245 1250
1246 Object& result = Object::Handle(); 1251 Object& result = Object::Handle();
1247 if (!ResolveCallThroughGetter(receiver, 1252 if (!ResolveCallThroughGetter(receiver,
1248 receiver_class, 1253 receiver_class,
1249 target_name, 1254 target_name,
1250 args_descriptor, 1255 args_descriptor,
1251 args, 1256 args,
1257 ic_data,
1252 &result)) { 1258 &result)) {
1253 ArgumentsDescriptor desc(args_descriptor); 1259 ArgumentsDescriptor desc(args_descriptor);
1254 const Function& target_function = Function::Handle( 1260 const Function& target_function =
1255 receiver_class.GetNoSuchMethodDispatcher(target_name, args_descriptor)); 1261 Function::Handle(receiver_class.GetInvocationDispatcher(
1262 target_name,
1263 args_descriptor,
1264 RawFunction::kNoSuchMethodDispatcher));
1256 // Update IC data. 1265 // Update IC data.
1257 ASSERT(!target_function.IsNull()); 1266 ASSERT(!target_function.IsNull());
1258 intptr_t receiver_cid = receiver.GetClassId(); 1267 intptr_t receiver_cid = receiver.GetClassId();
1259 if (ic_data.num_args_tested() == 1) { 1268 if (ic_data.num_args_tested() == 1) {
1260 // In optimized code we may enter into here via the 1269 // In optimized code we may enter into here via the
1261 // MegamorphicCacheMissHandler since noSuchMethod dispatchers are not 1270 // MegamorphicCacheMissHandler since noSuchMethod dispatchers are not
1262 // inserted into the megamorphic cache. Therefore, we need to guard 1271 // inserted into the megamorphic cache. Therefore, we need to guard
1263 // against entering the same check twice into the ICData. 1272 // against entering the same check twice into the ICData.
1264 // Note that num_args_tested == 1 in optimized code. 1273 // Note that num_args_tested == 1 in optimized code.
1265 // TODO(fschneider): Handle extraordinary cases like noSuchMethod and 1274 // TODO(fschneider): Handle extraordinary cases like noSuchMethod and
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after
1882 // Arg1: Value that is being stored. 1891 // Arg1: Value that is being stored.
1883 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { 1892 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) {
1884 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); 1893 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count());
1885 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); 1894 const Field& field = Field::CheckedHandle(arguments.ArgAt(0));
1886 const Object& value = Object::Handle(arguments.ArgAt(1)); 1895 const Object& value = Object::Handle(arguments.ArgAt(1));
1887 1896
1888 field.UpdateCid(value.GetClassId()); 1897 field.UpdateCid(value.GetClassId());
1889 } 1898 }
1890 1899
1891 } // namespace dart 1900 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/debugger.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698