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

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

Issue 11636025: Simplify method invocation runtime entries. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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/lib/invocation_mirror.cc ('k') | runtime/vm/dart_entry.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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_macros.h" 7 #include "vm/assembler_macros.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 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 kNumNamedArguments); 1084 kNumNamedArguments);
1085 ASSERT(!target_function.IsNull()); 1085 ASSERT(!target_function.IsNull());
1086 GrowableArray<intptr_t> class_ids(kNumArguments); 1086 GrowableArray<intptr_t> class_ids(kNumArguments);
1087 ASSERT(ic_data.num_args_tested() == kNumArguments); 1087 ASSERT(ic_data.num_args_tested() == kNumArguments);
1088 class_ids.Add(Class::Handle(receiver.clazz()).id()); 1088 class_ids.Add(Class::Handle(receiver.clazz()).id());
1089 class_ids.Add(Class::Handle(arg1.clazz()).id()); 1089 class_ids.Add(Class::Handle(arg1.clazz()).id());
1090 ic_data.AddCheck(class_ids, target_function); 1090 ic_data.AddCheck(class_ids, target_function);
1091 } 1091 }
1092 1092
1093 1093
1094 // Invoke appropriate noSuchMethod function.
1095 // Arg0: receiver.
1096 // Arg1: ic-data.
1097 // Arg2: arguments descriptor array.
1098 // Arg3: arguments array.
1099 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) {
1100 ASSERT(arguments.ArgCount() ==
1101 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count());
1102 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
1103 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
1104 const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(2));
1105 const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3));
1106
1107 const String& original_function_name = String::Handle(ic_data.target_name());
1108 const Object& result = Object::Handle(
1109 DartEntry::InvokeNoSuchMethod(receiver,
1110 original_function_name,
1111 orig_arguments,
1112 orig_arguments_desc));
1113 CheckResultError(result);
1114 arguments.SetReturn(result);
1115 }
1116
1117
1118 // A non-closure object was invoked as a closure, so call the "call" method
1119 // on it.
1120 // Arg0: non-closure object.
1121 // Arg1: arguments descriptor.
1122 // Arg2: arguments array, including non-closure object.
1123 DEFINE_RUNTIME_ENTRY(InvokeNonClosure, 3) {
1124 ASSERT(arguments.ArgCount() ==
1125 kInvokeNonClosureRuntimeEntry.argument_count());
1126 const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0));
1127 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(1));
1128 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(2));
1129
1130 const Object& result = Object::Handle(
1131 DartEntry::InvokeClosure(instance,
1132 function_args,
1133 args_descriptor));
1134 CheckResultError(result);
1135 arguments.SetReturn(result);
1136 }
1137
1138
1094 // An instance call could not be resolved by an IC miss handler. Check if 1139 // An instance call could not be resolved by an IC miss handler. Check if
1095 // it was a getter call and if there is an instance function with the same 1140 // it was a getter call and if there is an instance function with the same
1096 // name. If so, create and return an implicit closure from the function. 1141 // name. If so, create and return an implicit closure from the function.
1097 // Otherwise return null. 1142 // Otherwise return null.
1098 static RawInstance* ResolveImplicitClosure(const Instance& receiver, 1143 static RawInstance* ResolveImplicitClosure(const Instance& receiver,
1099 const Class& receiver_class, 1144 const Class& receiver_class,
1100 const String& target_name) { 1145 const String& target_name) {
1101 // 1. Check if was a getter call. 1146 // 1. Check if was a getter call.
1102 if (!Field::IsGetterName(target_name)) return Instance::null(); 1147 if (!Field::IsGetterName(target_name)) return Instance::null();
1103 1148
(...skipping 13 matching lines...) Expand all
1117 Instance::Handle(Closure::New(closure_function, context)); 1162 Instance::Handle(Closure::New(closure_function, context));
1118 if (receiver_class.HasTypeArguments()) { 1163 if (receiver_class.HasTypeArguments()) {
1119 const AbstractTypeArguments& type_arguments = 1164 const AbstractTypeArguments& type_arguments =
1120 AbstractTypeArguments::Handle(receiver.GetTypeArguments()); 1165 AbstractTypeArguments::Handle(receiver.GetTypeArguments());
1121 closure.SetTypeArguments(type_arguments); 1166 closure.SetTypeArguments(type_arguments);
1122 } 1167 }
1123 return closure.raw(); 1168 return closure.raw();
1124 } 1169 }
1125 1170
1126 1171
1127 static RawObject* InvokeNoSuchMethod(const Instance& receiver,
1128 const String& target_name,
1129 const Array& arguments_descriptor,
1130 const Array& arguments) {
1131 // Allocate an InvocationMirror object.
1132 const Library& core_lib = Library::Handle(Library::CoreLibrary());
1133 const String& invocation_mirror_name =
1134 String::Handle(Symbols::InvocationMirror());
1135 Class& invocation_mirror_class =
1136 Class::Handle(core_lib.LookupClassAllowPrivate(invocation_mirror_name));
1137 ASSERT(!invocation_mirror_class.IsNull());
1138 const String& allocation_function_name =
1139 String::Handle(Symbols::AllocateInvocationMirror());
1140 const Function& allocation_function = Function::Handle(
1141 Resolver::ResolveStaticByName(invocation_mirror_class,
1142 allocation_function_name,
1143 Resolver::kIsQualified));
1144 ASSERT(!allocation_function.IsNull());
1145 const int kNumAllocationArgs = 3;
1146 const Array& allocation_args = Array::Handle(Array::New(kNumAllocationArgs));
1147 allocation_args.SetAt(0, target_name);
1148 allocation_args.SetAt(1, arguments_descriptor);
1149 allocation_args.SetAt(2, arguments);
1150 const Object& invocation_mirror =
1151 Object::Handle(DartEntry::InvokeStatic(allocation_function,
1152 allocation_args));
1153
1154 // Now use the invocation mirror object and invoke NoSuchMethod.
1155 const String& function_name = String::Handle(Symbols::NoSuchMethod());
1156 const int kNumArguments = 2;
1157 const int kNumNamedArguments = 0;
1158 const Function& function = Function::Handle(
1159 Resolver::ResolveDynamic(receiver,
1160 function_name,
1161 kNumArguments,
1162 kNumNamedArguments));
1163 ASSERT(!function.IsNull());
1164 const Array& args = Array::Handle(Array::New(kNumArguments));
1165 args.SetAt(0, receiver);
1166 args.SetAt(1, invocation_mirror);
1167 const Object& result = Object::Handle(DartEntry::InvokeDynamic(function,
1168 args));
1169 CheckResultError(result);
1170 return result.raw();
1171 }
1172
1173
1174 static RawObject* InvokeNonClosure(const Instance& receiver,
1175 const Class& receiver_class,
1176 const Array& arguments_descriptor,
1177 const Array& arguments) {
1178 // Resolve and invoke the "call" method if it exists.
1179 const String& call_symbol = String::Handle(Symbols::Call());
1180
1181 Class& current_class = Class::Handle(receiver_class.raw());
1182 Function& call_function = Function::Handle();
1183 do {
1184 call_function = current_class.LookupDynamicFunction(call_symbol);
1185
1186 if (!call_function.IsNull()) {
1187 // The non-closure object is passed as implicit first argument
1188 // (receiver). It is already included in the arguments array.
1189
1190 // Now call the invoke stub which will invoke the call method.
1191 const Object& result =
1192 Object::Handle(DartEntry::InvokeDynamic(call_function,
1193 arguments,
1194 arguments_descriptor));
1195 CheckResultError(result);
1196 return result.raw();
1197 }
1198
1199 current_class = current_class.SuperClass();
1200 } while (!current_class.IsNull());
1201
1202 // There is no 'call' method, so invoke noSuchMethod.
1203 return InvokeNoSuchMethod(receiver,
1204 call_symbol,
1205 arguments_descriptor,
1206 arguments);
1207 }
1208
1209
1210 // An instance call of the form o.f(...) could not be resolved. Check if 1172 // An instance call of the form o.f(...) could not be resolved. Check if
1211 // there is a getter with the same name. If so, invoke it. If the value is 1173 // there is a getter with the same name. If so, invoke it. If the value is
1212 // a closure, invoke it with the given arguments. If the value is a 1174 // a closure, invoke it with the given arguments. If the value is a
1213 // non-closure, attempt to invoke "call" on it. 1175 // non-closure, attempt to invoke "call" on it.
1214 static bool ResolveCallThroughGetter(const Instance& receiver, 1176 static bool ResolveCallThroughGetter(const Instance& receiver,
1215 const Class& receiver_class, 1177 const Class& receiver_class,
1216 const String& target_name, 1178 const String& target_name,
1217 const Array& arguments_descriptor, 1179 const Array& arguments_descriptor,
1218 const Array& arguments, 1180 const Array& arguments,
1219 Object* result) { 1181 Object* result) {
(...skipping 10 matching lines...) Expand all
1230 1192
1231 // 2. Invoke the getter. 1193 // 2. Invoke the getter.
1232 const Array& args = Array::Handle(Array::New(kNumArguments)); 1194 const Array& args = Array::Handle(Array::New(kNumArguments));
1233 args.SetAt(0, receiver); 1195 args.SetAt(0, receiver);
1234 const Object& value = Object::Handle(DartEntry::InvokeDynamic(getter, args)); 1196 const Object& value = Object::Handle(DartEntry::InvokeDynamic(getter, args));
1235 1197
1236 // 3. If the getter threw an exception, treat it as no such method. 1198 // 3. If the getter threw an exception, treat it as no such method.
1237 if (value.IsUnhandledException()) return false; 1199 if (value.IsUnhandledException()) return false;
1238 1200
1239 // 4. If there was some other error, propagate it. 1201 // 4. If there was some other error, propagate it.
1240 if (value.IsError()) { 1202 CheckResultError(value);
1241 Exceptions::PropagateError(Error::Cast(value));
1242 }
1243 1203
1244 // 5. If the value is a closure, invoke it and return the result. If it 1204 // 5. Invoke the value as a closure.
1245 // is a non-closure, invoke "call" on it and return the result.
1246 Instance& instance = Instance::Handle(); 1205 Instance& instance = Instance::Handle();
1247 instance ^= value.raw(); 1206 instance ^= value.raw();
1248 const Class& instance_class = Class::Handle(instance.clazz()); 1207 arguments.SetAt(0, instance);
1249 ASSERT(!instance_class.IsNull()); 1208 *result = DartEntry::InvokeClosure(instance,
1250 // An object is a closure iff. its class has a non-null signature function. 1209 arguments,
1251 if (instance_class.signature_function() != Function::null()) { 1210 arguments_descriptor);
1252 // The closure object is passed as implicit first argument to closure 1211 CheckResultError(*result);
1253 // functions, since it may be needed to throw a NoSuchMethodError, in case
1254 // the wrong number of arguments is passed.
1255 // Replace the original receiver in the arguments array by the closure.
1256 arguments.SetAt(0, instance);
1257 *result = DartEntry::InvokeClosure(instance,
1258 arguments,
1259 arguments_descriptor);
1260 CheckResultError(*result);
1261 } else {
1262 *result = InvokeNonClosure(instance,
1263 instance_class,
1264 arguments_descriptor,
1265 arguments);
1266 }
1267 return true; 1212 return true;
1268 } 1213 }
1269 1214
1270 1215
1271 // Invoke appropriate noSuchMethod function.
1272 // Arg0: receiver.
1273 // Arg1: ic-data.
1274 // Arg2: arguments descriptor array.
1275 // Arg3: arguments array.
1276 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) {
1277 ASSERT(arguments.ArgCount() ==
1278 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count());
1279 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
1280 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
1281 const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(2));
1282 const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3));
1283
1284 const String& original_function_name = String::Handle(ic_data.target_name());
1285 const Object& result =
1286 Object::Handle(InvokeNoSuchMethod(receiver,
1287 original_function_name,
1288 orig_arguments_desc,
1289 orig_arguments));
1290 arguments.SetReturn(result);
1291 }
1292
1293
1294 // A non-closure object was invoked as a closure, so call the "call" method
1295 // on it.
1296 // Arg0: non-closure object.
1297 // Arg1: arguments descriptor.
1298 // Arg2: arguments array, including non-closure object.
1299 DEFINE_RUNTIME_ENTRY(InvokeNonClosure, 3) {
1300 ASSERT(arguments.ArgCount() ==
1301 kInvokeNonClosureRuntimeEntry.argument_count());
1302 const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0));
1303 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(1));
1304 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(2));
1305
1306 const Class& instance_class = Class::Handle(instance.clazz());
1307 const Object& result = Object::Handle(InvokeNonClosure(instance,
1308 instance_class,
1309 args_descriptor,
1310 function_args));
1311 arguments.SetReturn(result);
1312 }
1313
1314
1315 // The IC miss handler has failed to find a (cacheable) instance function to 1216 // The IC miss handler has failed to find a (cacheable) instance function to
1316 // invoke. Handle three possibilities: 1217 // invoke. Handle three possibilities:
1317 // 1218 //
1318 // 1. If the call was a getter o.f, there may be an instance function with 1219 // 1. If the call was a getter o.f, there may be an instance function with
1319 // the same name. If so, create an implicit closure and return it. 1220 // the same name. If so, create an implicit closure and return it.
1320 // 1221 //
1321 // 2. If the call was an instance call o.f(...), there may be a getter with 1222 // 2. If the call was an instance call o.f(...), there may be a getter with
1322 // the same name. If so, invoke it. If the value is a closure, invoke 1223 // the same name. If so, invoke it. If the value is a closure, invoke
1323 // it with the given arguments. If the value is a non-closure, attempt 1224 // it with the given arguments. If the value is a non-closure, attempt
1324 // to invoke "call" on it. 1225 // to invoke "call" on it.
(...skipping 22 matching lines...) Expand all
1347 return; 1248 return;
1348 } 1249 }
1349 1250
1350 Object& result = Object::Handle(); 1251 Object& result = Object::Handle();
1351 if (!ResolveCallThroughGetter(receiver, 1252 if (!ResolveCallThroughGetter(receiver,
1352 receiver_class, 1253 receiver_class,
1353 target_name, 1254 target_name,
1354 args_descriptor, 1255 args_descriptor,
1355 args, 1256 args,
1356 &result)) { 1257 &result)) {
1357 result = InvokeNoSuchMethod(receiver, target_name, args_descriptor, args); 1258 result = DartEntry::InvokeNoSuchMethod(receiver,
1259 target_name,
1260 args,
1261 args_descriptor);
1358 } 1262 }
1263 CheckResultError(result);
1359 arguments.SetReturn(result); 1264 arguments.SetReturn(result);
1360 } 1265 }
1361 1266
1362 1267
1363 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { 1268 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) {
1364 ASSERT(arguments.ArgCount() == 1269 ASSERT(arguments.ArgCount() ==
1365 kStackOverflowRuntimeEntry.argument_count()); 1270 kStackOverflowRuntimeEntry.argument_count());
1366 uword stack_pos = reinterpret_cast<uword>(&arguments); 1271 uword stack_pos = reinterpret_cast<uword>(&arguments);
1367 1272
1368 // If an interrupt happens at the same time as a stack overflow, we 1273 // If an interrupt happens at the same time as a stack overflow, we
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 return; 1797 return;
1893 } 1798 }
1894 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); 1799 HeapTrace* heap_trace = Isolate::Current()->heap()->trace();
1895 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), 1800 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object),
1896 field_addr, 1801 field_addr,
1897 RawObject::ToAddr(value)); 1802 RawObject::ToAddr(value));
1898 } 1803 }
1899 END_LEAF_RUNTIME_ENTRY 1804 END_LEAF_RUNTIME_ENTRY
1900 1805
1901 } // namespace dart 1806 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/invocation_mirror.cc ('k') | runtime/vm/dart_entry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698