| OLD | NEW |
| 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/code_patcher.h" | 9 #include "vm/code_patcher.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 "Traces all failed optimization attempts"); | 49 "Traces all failed optimization attempts"); |
| 50 DEFINE_FLAG(bool, trace_optimized_ic_calls, false, | 50 DEFINE_FLAG(bool, trace_optimized_ic_calls, false, |
| 51 "Trace IC calls in optimized code."); | 51 "Trace IC calls in optimized code."); |
| 52 DEFINE_FLAG(int, reoptimization_counter_threshold, 2000, | 52 DEFINE_FLAG(int, reoptimization_counter_threshold, 2000, |
| 53 "Counter threshold before a function gets reoptimized."); | 53 "Counter threshold before a function gets reoptimized."); |
| 54 DEFINE_FLAG(int, max_subtype_cache_entries, 100, | 54 DEFINE_FLAG(int, max_subtype_cache_entries, 100, |
| 55 "Maximum number of subtype cache entries (number of checks cached)."); | 55 "Maximum number of subtype cache entries (number of checks cached)."); |
| 56 | 56 |
| 57 | 57 |
| 58 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { | 58 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { |
| 59 ASSERT(arguments.Count() == kTraceFunctionEntryRuntimeEntry.argument_count()); | 59 ASSERT(arguments.ArgCount() == |
| 60 const Function& function = Function::CheckedHandle(arguments.At(0)); | 60 kTraceFunctionEntryRuntimeEntry.argument_count()); |
| 61 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 61 const String& function_name = String::Handle(function.name()); | 62 const String& function_name = String::Handle(function.name()); |
| 62 const String& class_name = | 63 const String& class_name = |
| 63 String::Handle(Class::Handle(function.Owner()).Name()); | 64 String::Handle(Class::Handle(function.Owner()).Name()); |
| 64 OS::Print("> Entering '%s.%s'\n", | 65 OS::Print("> Entering '%s.%s'\n", |
| 65 class_name.ToCString(), function_name.ToCString()); | 66 class_name.ToCString(), function_name.ToCString()); |
| 66 } | 67 } |
| 67 | 68 |
| 68 | 69 |
| 69 DEFINE_RUNTIME_ENTRY(TraceFunctionExit, 1) { | 70 DEFINE_RUNTIME_ENTRY(TraceFunctionExit, 1) { |
| 70 ASSERT(arguments.Count() == kTraceFunctionExitRuntimeEntry.argument_count()); | 71 ASSERT(arguments.ArgCount() == |
| 71 const Function& function = Function::CheckedHandle(arguments.At(0)); | 72 kTraceFunctionExitRuntimeEntry.argument_count()); |
| 73 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 72 const String& function_name = String::Handle(function.name()); | 74 const String& function_name = String::Handle(function.name()); |
| 73 const String& class_name = | 75 const String& class_name = |
| 74 String::Handle(Class::Handle(function.Owner()).Name()); | 76 String::Handle(Class::Handle(function.Owner()).Name()); |
| 75 OS::Print("< Exiting '%s.%s'\n", | 77 OS::Print("< Exiting '%s.%s'\n", |
| 76 class_name.ToCString(), function_name.ToCString()); | 78 class_name.ToCString(), function_name.ToCString()); |
| 77 } | 79 } |
| 78 | 80 |
| 79 | 81 |
| 80 // Allocation of a fixed length array of given element type. | 82 // Allocation of a fixed length array of given element type. |
| 81 // This runtime entry is never called for allocating a List of a generic type, | 83 // This runtime entry is never called for allocating a List of a generic type, |
| 82 // because a prior run time call instantiates the element type if necessary. | 84 // because a prior run time call instantiates the element type if necessary. |
| 83 // Arg0: array length. | 85 // Arg0: array length. |
| 84 // Arg1: array element type. | 86 // Arg1: array element type. |
| 85 // Return value: newly allocated array of length arg0. | 87 // Return value: newly allocated array of length arg0. |
| 86 DEFINE_RUNTIME_ENTRY(AllocateArray, 2) { | 88 DEFINE_RUNTIME_ENTRY(AllocateArray, 2) { |
| 87 ASSERT(arguments.Count() == kAllocateArrayRuntimeEntry.argument_count()); | 89 ASSERT(arguments.ArgCount() == kAllocateArrayRuntimeEntry.argument_count()); |
| 88 const Smi& length = Smi::CheckedHandle(arguments.At(0)); | 90 const Smi& length = Smi::CheckedHandle(arguments.ArgAt(0)); |
| 89 const Array& array = Array::Handle(Array::New(length.Value())); | 91 const Array& array = Array::Handle(Array::New(length.Value())); |
| 90 arguments.SetReturn(array); | 92 arguments.SetReturn(array); |
| 91 AbstractTypeArguments& element_type = | 93 AbstractTypeArguments& element_type = |
| 92 AbstractTypeArguments::CheckedHandle(arguments.At(1)); | 94 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 93 // An Array is raw or takes only one type argument. | 95 // An Array is raw or takes only one type argument. |
| 94 ASSERT(element_type.IsNull() || | 96 ASSERT(element_type.IsNull() || |
| 95 ((element_type.Length() == 1) && element_type.IsInstantiated())); | 97 ((element_type.Length() == 1) && element_type.IsInstantiated())); |
| 96 array.SetTypeArguments(element_type); // May be null. | 98 array.SetTypeArguments(element_type); // May be null. |
| 97 } | 99 } |
| 98 | 100 |
| 99 | 101 |
| 100 // Allocate a new object. | 102 // Allocate a new object. |
| 101 // Arg0: class of the object that needs to be allocated. | 103 // Arg0: class of the object that needs to be allocated. |
| 102 // Arg1: type arguments of the object that needs to be allocated. | 104 // Arg1: type arguments of the object that needs to be allocated. |
| 103 // Arg2: type arguments of the instantiator or kNoInstantiator. | 105 // Arg2: type arguments of the instantiator or kNoInstantiator. |
| 104 // Return value: newly allocated object. | 106 // Return value: newly allocated object. |
| 105 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) { | 107 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) { |
| 106 ASSERT(arguments.Count() == kAllocateObjectRuntimeEntry.argument_count()); | 108 ASSERT(arguments.ArgCount() == kAllocateObjectRuntimeEntry.argument_count()); |
| 107 const Class& cls = Class::CheckedHandle(arguments.At(0)); | 109 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); |
| 108 const Instance& instance = Instance::Handle(Instance::New(cls)); | 110 const Instance& instance = Instance::Handle(Instance::New(cls)); |
| 109 arguments.SetReturn(instance); | 111 arguments.SetReturn(instance); |
| 110 if (!cls.HasTypeArguments()) { | 112 if (!cls.HasTypeArguments()) { |
| 111 // No type arguments required for a non-parameterized type. | 113 // No type arguments required for a non-parameterized type. |
| 112 ASSERT(Instance::CheckedHandle(arguments.At(1)).IsNull()); | 114 ASSERT(Instance::CheckedHandle(arguments.ArgAt(1)).IsNull()); |
| 113 return; | 115 return; |
| 114 } | 116 } |
| 115 AbstractTypeArguments& type_arguments = | 117 AbstractTypeArguments& type_arguments = |
| 116 AbstractTypeArguments::CheckedHandle(arguments.At(1)); | 118 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 117 ASSERT(type_arguments.IsNull() || | 119 ASSERT(type_arguments.IsNull() || |
| 118 (type_arguments.Length() == cls.NumTypeArguments())); | 120 (type_arguments.Length() == cls.NumTypeArguments())); |
| 119 // If no instantiator is provided, set the type arguments and return. | 121 // If no instantiator is provided, set the type arguments and return. |
| 120 if (Object::Handle(arguments.At(2)).IsSmi()) { | 122 if (Object::Handle(arguments.ArgAt(2)).IsSmi()) { |
| 121 ASSERT(Smi::CheckedHandle(arguments.At(2)).Value() == | 123 ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() == |
| 122 StubCode::kNoInstantiator); | 124 StubCode::kNoInstantiator); |
| 123 instance.SetTypeArguments(type_arguments); // May be null. | 125 instance.SetTypeArguments(type_arguments); // May be null. |
| 124 return; | 126 return; |
| 125 } | 127 } |
| 126 ASSERT(!type_arguments.IsInstantiated()); | 128 ASSERT(!type_arguments.IsInstantiated()); |
| 127 const AbstractTypeArguments& instantiator = | 129 const AbstractTypeArguments& instantiator = |
| 128 AbstractTypeArguments::CheckedHandle(arguments.At(2)); | 130 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(2)); |
| 129 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); | 131 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); |
| 130 if (instantiator.IsNull()) { | 132 if (instantiator.IsNull()) { |
| 131 type_arguments = | 133 type_arguments = |
| 132 InstantiatedTypeArguments::New(type_arguments, instantiator); | 134 InstantiatedTypeArguments::New(type_arguments, instantiator); |
| 133 } else if (instantiator.IsTypeArguments()) { | 135 } else if (instantiator.IsTypeArguments()) { |
| 134 // Code inlined in the caller should have optimized the case where the | 136 // Code inlined in the caller should have optimized the case where the |
| 135 // instantiator is a TypeArguments and can be used as type argument vector. | 137 // instantiator is a TypeArguments and can be used as type argument vector. |
| 136 ASSERT(!type_arguments.IsUninstantiatedIdentity() || | 138 ASSERT(!type_arguments.IsUninstantiatedIdentity() || |
| 137 (instantiator.Length() != type_arguments.Length())); | 139 (instantiator.Length() != type_arguments.Length())); |
| 138 type_arguments = | 140 type_arguments = |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 | 173 |
| 172 | 174 |
| 173 // Allocate a new object of a generic type and check that the instantiated type | 175 // Allocate a new object of a generic type and check that the instantiated type |
| 174 // arguments are within the declared bounds or throw a dynamic type error. | 176 // arguments are within the declared bounds or throw a dynamic type error. |
| 175 // Arg0: class of the object that needs to be allocated. | 177 // Arg0: class of the object that needs to be allocated. |
| 176 // Arg1: type arguments of the object that needs to be allocated. | 178 // Arg1: type arguments of the object that needs to be allocated. |
| 177 // Arg2: type arguments of the instantiator or kNoInstantiator. | 179 // Arg2: type arguments of the instantiator or kNoInstantiator. |
| 178 // Return value: newly allocated object. | 180 // Return value: newly allocated object. |
| 179 DEFINE_RUNTIME_ENTRY(AllocateObjectWithBoundsCheck, 3) { | 181 DEFINE_RUNTIME_ENTRY(AllocateObjectWithBoundsCheck, 3) { |
| 180 ASSERT(FLAG_enable_type_checks); | 182 ASSERT(FLAG_enable_type_checks); |
| 181 ASSERT(arguments.Count() == | 183 ASSERT(arguments.ArgCount() == |
| 182 kAllocateObjectWithBoundsCheckRuntimeEntry.argument_count()); | 184 kAllocateObjectWithBoundsCheckRuntimeEntry.argument_count()); |
| 183 const Class& cls = Class::CheckedHandle(arguments.At(0)); | 185 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); |
| 184 const Instance& instance = Instance::Handle(Instance::New(cls)); | 186 const Instance& instance = Instance::Handle(Instance::New(cls)); |
| 185 arguments.SetReturn(instance); | 187 arguments.SetReturn(instance); |
| 186 ASSERT(cls.HasTypeArguments()); | 188 ASSERT(cls.HasTypeArguments()); |
| 187 AbstractTypeArguments& type_arguments = | 189 AbstractTypeArguments& type_arguments = |
| 188 AbstractTypeArguments::CheckedHandle(arguments.At(1)); | 190 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 189 ASSERT(type_arguments.IsNull() || | 191 ASSERT(type_arguments.IsNull() || |
| 190 (type_arguments.Length() == cls.NumTypeArguments())); | 192 (type_arguments.Length() == cls.NumTypeArguments())); |
| 191 AbstractTypeArguments& bounds_instantiator = AbstractTypeArguments::Handle(); | 193 AbstractTypeArguments& bounds_instantiator = AbstractTypeArguments::Handle(); |
| 192 if (Object::Handle(arguments.At(2)).IsSmi()) { | 194 if (Object::Handle(arguments.ArgAt(2)).IsSmi()) { |
| 193 ASSERT(Smi::CheckedHandle(arguments.At(2)).Value() == | 195 ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() == |
| 194 StubCode::kNoInstantiator); | 196 StubCode::kNoInstantiator); |
| 195 } else { | 197 } else { |
| 196 ASSERT(!type_arguments.IsInstantiated()); | 198 ASSERT(!type_arguments.IsInstantiated()); |
| 197 const AbstractTypeArguments& instantiator = | 199 const AbstractTypeArguments& instantiator = |
| 198 AbstractTypeArguments::CheckedHandle(arguments.At(2)); | 200 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(2)); |
| 199 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); | 201 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); |
| 200 if (instantiator.IsNull()) { | 202 if (instantiator.IsNull()) { |
| 201 type_arguments = | 203 type_arguments = |
| 202 InstantiatedTypeArguments::New(type_arguments, instantiator); | 204 InstantiatedTypeArguments::New(type_arguments, instantiator); |
| 203 } else if (instantiator.IsTypeArguments()) { | 205 } else if (instantiator.IsTypeArguments()) { |
| 204 // Code inlined in the caller should have optimized the case where the | 206 // Code inlined in the caller should have optimized the case where the |
| 205 // instantiator is a TypeArguments and can be used as type argument | 207 // instantiator is a TypeArguments and can be used as type argument |
| 206 // vector. | 208 // vector. |
| 207 ASSERT(!type_arguments.IsUninstantiatedIdentity() || | 209 ASSERT(!type_arguments.IsUninstantiatedIdentity() || |
| 208 (instantiator.Length() != type_arguments.Length())); | 210 (instantiator.Length() != type_arguments.Length())); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 239 } | 241 } |
| 240 instance.SetTypeArguments(type_arguments); | 242 instance.SetTypeArguments(type_arguments); |
| 241 } | 243 } |
| 242 | 244 |
| 243 | 245 |
| 244 // Instantiate type arguments. | 246 // Instantiate type arguments. |
| 245 // Arg0: uninstantiated type arguments. | 247 // Arg0: uninstantiated type arguments. |
| 246 // Arg1: instantiator type arguments. | 248 // Arg1: instantiator type arguments. |
| 247 // Return value: instantiated type arguments. | 249 // Return value: instantiated type arguments. |
| 248 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { | 250 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { |
| 249 ASSERT(arguments.Count() == | 251 ASSERT(arguments.ArgCount() == |
| 250 kInstantiateTypeArgumentsRuntimeEntry.argument_count()); | 252 kInstantiateTypeArgumentsRuntimeEntry.argument_count()); |
| 251 AbstractTypeArguments& type_arguments = | 253 AbstractTypeArguments& type_arguments = |
| 252 AbstractTypeArguments::CheckedHandle(arguments.At(0)); | 254 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(0)); |
| 253 const AbstractTypeArguments& instantiator = | 255 const AbstractTypeArguments& instantiator = |
| 254 AbstractTypeArguments::CheckedHandle(arguments.At(1)); | 256 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 255 ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated()); | 257 ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated()); |
| 256 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); | 258 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); |
| 257 // Code inlined in the caller should have optimized the case where the | 259 // Code inlined in the caller should have optimized the case where the |
| 258 // instantiator can be used as type argument vector. | 260 // instantiator can be used as type argument vector. |
| 259 ASSERT(instantiator.IsNull() || | 261 ASSERT(instantiator.IsNull() || |
| 260 !type_arguments.IsUninstantiatedIdentity() || | 262 !type_arguments.IsUninstantiatedIdentity() || |
| 261 !instantiator.IsTypeArguments() || | 263 !instantiator.IsTypeArguments() || |
| 262 (instantiator.Length() != type_arguments.Length())); | 264 (instantiator.Length() != type_arguments.Length())); |
| 263 type_arguments = InstantiatedTypeArguments::New(type_arguments, instantiator); | 265 type_arguments = InstantiatedTypeArguments::New(type_arguments, instantiator); |
| 264 ASSERT(type_arguments.IsInstantiated()); | 266 ASSERT(type_arguments.IsInstantiated()); |
| 265 arguments.SetReturn(type_arguments); | 267 arguments.SetReturn(type_arguments); |
| 266 } | 268 } |
| 267 | 269 |
| 268 | 270 |
| 269 // Allocate a new closure. | 271 // Allocate a new closure. |
| 270 // The type argument vector of a closure is always the vector of type parameters | 272 // The type argument vector of a closure is always the vector of type parameters |
| 271 // of its signature class, i.e. an uninstantiated identity vector. Therefore, | 273 // of its signature class, i.e. an uninstantiated identity vector. Therefore, |
| 272 // the instantiator type arguments can be used as the instantiated closure type | 274 // the instantiator type arguments can be used as the instantiated closure type |
| 273 // arguments and is passed here as the type arguments. | 275 // arguments and is passed here as the type arguments. |
| 274 // Arg0: local function. | 276 // Arg0: local function. |
| 275 // Arg1: type arguments of the closure (i.e. instantiator). | 277 // Arg1: type arguments of the closure (i.e. instantiator). |
| 276 // Return value: newly allocated closure. | 278 // Return value: newly allocated closure. |
| 277 DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) { | 279 DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) { |
| 278 ASSERT(arguments.Count() == kAllocateClosureRuntimeEntry.argument_count()); | 280 ASSERT(arguments.ArgCount() == kAllocateClosureRuntimeEntry.argument_count()); |
| 279 const Function& function = Function::CheckedHandle(arguments.At(0)); | 281 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 280 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction()); | 282 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction()); |
| 281 const AbstractTypeArguments& type_arguments = | 283 const AbstractTypeArguments& type_arguments = |
| 282 AbstractTypeArguments::CheckedHandle(arguments.At(1)); | 284 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 283 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); | 285 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); |
| 284 // The current context was saved in the Isolate structure when entering the | 286 // The current context was saved in the Isolate structure when entering the |
| 285 // runtime. | 287 // runtime. |
| 286 const Context& context = Context::Handle(isolate->top_context()); | 288 const Context& context = Context::Handle(isolate->top_context()); |
| 287 ASSERT(!context.IsNull()); | 289 ASSERT(!context.IsNull()); |
| 288 const Instance& closure = Instance::Handle(Closure::New(function, context)); | 290 const Instance& closure = Instance::Handle(Closure::New(function, context)); |
| 289 Closure::SetTypeArguments(closure, type_arguments); | 291 Closure::SetTypeArguments(closure, type_arguments); |
| 290 arguments.SetReturn(closure); | 292 arguments.SetReturn(closure); |
| 291 } | 293 } |
| 292 | 294 |
| 293 | 295 |
| 294 // Allocate a new implicit static closure. | 296 // Allocate a new implicit static closure. |
| 295 // Arg0: local function. | 297 // Arg0: local function. |
| 296 // Return value: newly allocated closure. | 298 // Return value: newly allocated closure. |
| 297 DEFINE_RUNTIME_ENTRY(AllocateImplicitStaticClosure, 1) { | 299 DEFINE_RUNTIME_ENTRY(AllocateImplicitStaticClosure, 1) { |
| 298 ASSERT(arguments.Count() == | 300 ASSERT(arguments.ArgCount() == |
| 299 kAllocateImplicitStaticClosureRuntimeEntry.argument_count()); | 301 kAllocateImplicitStaticClosureRuntimeEntry.argument_count()); |
| 300 ObjectStore* object_store = isolate->object_store(); | 302 ObjectStore* object_store = isolate->object_store(); |
| 301 ASSERT(object_store != NULL); | 303 ASSERT(object_store != NULL); |
| 302 const Function& function = Function::CheckedHandle(arguments.At(0)); | 304 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 303 ASSERT(!function.IsNull()); | 305 ASSERT(!function.IsNull()); |
| 304 ASSERT(function.IsImplicitStaticClosureFunction()); | 306 ASSERT(function.IsImplicitStaticClosureFunction()); |
| 305 const Context& context = Context::Handle(object_store->empty_context()); | 307 const Context& context = Context::Handle(object_store->empty_context()); |
| 306 arguments.SetReturn(Instance::Handle(Closure::New(function, context))); | 308 arguments.SetReturn(Instance::Handle(Closure::New(function, context))); |
| 307 } | 309 } |
| 308 | 310 |
| 309 | 311 |
| 310 // Allocate a new implicit instance closure. | 312 // Allocate a new implicit instance closure. |
| 311 // Arg0: local function. | 313 // Arg0: local function. |
| 312 // Arg1: receiver object. | 314 // Arg1: receiver object. |
| 313 // Arg2: type arguments of the closure. | 315 // Arg2: type arguments of the closure. |
| 314 // Return value: newly allocated closure. | 316 // Return value: newly allocated closure. |
| 315 DEFINE_RUNTIME_ENTRY(AllocateImplicitInstanceClosure, 3) { | 317 DEFINE_RUNTIME_ENTRY(AllocateImplicitInstanceClosure, 3) { |
| 316 ASSERT(arguments.Count() == | 318 ASSERT(arguments.ArgCount() == |
| 317 kAllocateImplicitInstanceClosureRuntimeEntry.argument_count()); | 319 kAllocateImplicitInstanceClosureRuntimeEntry.argument_count()); |
| 318 const Function& function = Function::CheckedHandle(arguments.At(0)); | 320 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 319 ASSERT(function.IsImplicitInstanceClosureFunction()); | 321 ASSERT(function.IsImplicitInstanceClosureFunction()); |
| 320 const Instance& receiver = Instance::CheckedHandle(arguments.At(1)); | 322 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 321 const AbstractTypeArguments& type_arguments = | 323 const AbstractTypeArguments& type_arguments = |
| 322 AbstractTypeArguments::CheckedHandle(arguments.At(2)); | 324 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(2)); |
| 323 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); | 325 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); |
| 324 Context& context = Context::Handle(); | 326 Context& context = Context::Handle(); |
| 325 context = Context::New(1); | 327 context = Context::New(1); |
| 326 context.SetAt(0, receiver); | 328 context.SetAt(0, receiver); |
| 327 const Instance& closure = Instance::Handle(Closure::New(function, context)); | 329 const Instance& closure = Instance::Handle(Closure::New(function, context)); |
| 328 Closure::SetTypeArguments(closure, type_arguments); | 330 Closure::SetTypeArguments(closure, type_arguments); |
| 329 arguments.SetReturn(closure); | 331 arguments.SetReturn(closure); |
| 330 } | 332 } |
| 331 | 333 |
| 332 | 334 |
| 333 // Allocate a new context large enough to hold the given number of variables. | 335 // Allocate a new context large enough to hold the given number of variables. |
| 334 // Arg0: number of variables. | 336 // Arg0: number of variables. |
| 335 // Return value: newly allocated context. | 337 // Return value: newly allocated context. |
| 336 DEFINE_RUNTIME_ENTRY(AllocateContext, 1) { | 338 DEFINE_RUNTIME_ENTRY(AllocateContext, 1) { |
| 337 ASSERT(arguments.Count() == kAllocateContextRuntimeEntry.argument_count()); | 339 ASSERT(arguments.ArgCount() == kAllocateContextRuntimeEntry.argument_count()); |
| 338 const Smi& num_variables = Smi::CheckedHandle(arguments.At(0)); | 340 const Smi& num_variables = Smi::CheckedHandle(arguments.ArgAt(0)); |
| 339 arguments.SetReturn(Context::Handle(Context::New(num_variables.Value()))); | 341 arguments.SetReturn(Context::Handle(Context::New(num_variables.Value()))); |
| 340 } | 342 } |
| 341 | 343 |
| 342 | 344 |
| 343 // Make a copy of the given context, including the values of the captured | 345 // Make a copy of the given context, including the values of the captured |
| 344 // variables. | 346 // variables. |
| 345 // Arg0: the context to be cloned. | 347 // Arg0: the context to be cloned. |
| 346 // Return value: newly allocated context. | 348 // Return value: newly allocated context. |
| 347 DEFINE_RUNTIME_ENTRY(CloneContext, 1) { | 349 DEFINE_RUNTIME_ENTRY(CloneContext, 1) { |
| 348 ASSERT(arguments.Count() == kCloneContextRuntimeEntry.argument_count()); | 350 ASSERT(arguments.ArgCount() == kCloneContextRuntimeEntry.argument_count()); |
| 349 const Context& ctx = Context::CheckedHandle(arguments.At(0)); | 351 const Context& ctx = Context::CheckedHandle(arguments.ArgAt(0)); |
| 350 Context& cloned_ctx = Context::Handle(Context::New(ctx.num_variables())); | 352 Context& cloned_ctx = Context::Handle(Context::New(ctx.num_variables())); |
| 351 cloned_ctx.set_parent(Context::Handle(ctx.parent())); | 353 cloned_ctx.set_parent(Context::Handle(ctx.parent())); |
| 352 for (int i = 0; i < ctx.num_variables(); i++) { | 354 for (int i = 0; i < ctx.num_variables(); i++) { |
| 353 cloned_ctx.SetAt(i, Instance::Handle(ctx.At(i))); | 355 cloned_ctx.SetAt(i, Instance::Handle(ctx.At(i))); |
| 354 } | 356 } |
| 355 arguments.SetReturn(cloned_ctx); | 357 arguments.SetReturn(cloned_ctx); |
| 356 } | 358 } |
| 357 | 359 |
| 358 | 360 |
| 359 // Helper routine for tracing a type check. | 361 // Helper routine for tracing a type check. |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 | 574 |
| 573 // Check that the given instance is an instance of the given type. | 575 // Check that the given instance is an instance of the given type. |
| 574 // Tested instance may not be null, because the null test is inlined. | 576 // Tested instance may not be null, because the null test is inlined. |
| 575 // Arg0: instance being checked. | 577 // Arg0: instance being checked. |
| 576 // Arg1: type. | 578 // Arg1: type. |
| 577 // Arg2: instantiator (or null). | 579 // Arg2: instantiator (or null). |
| 578 // Arg3: type arguments of the instantiator of the type. | 580 // Arg3: type arguments of the instantiator of the type. |
| 579 // Arg4: SubtypeTestCache. | 581 // Arg4: SubtypeTestCache. |
| 580 // Return value: true or false, or may throw a type error in checked mode. | 582 // Return value: true or false, or may throw a type error in checked mode. |
| 581 DEFINE_RUNTIME_ENTRY(Instanceof, 5) { | 583 DEFINE_RUNTIME_ENTRY(Instanceof, 5) { |
| 582 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count()); | 584 ASSERT(arguments.ArgCount() == kInstanceofRuntimeEntry.argument_count()); |
| 583 const Instance& instance = Instance::CheckedHandle(arguments.At(0)); | 585 const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 584 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(1)); | 586 const AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(1)); |
| 585 const Instance& instantiator = Instance::CheckedHandle(arguments.At(2)); | 587 const Instance& instantiator = Instance::CheckedHandle(arguments.ArgAt(2)); |
| 586 const AbstractTypeArguments& instantiator_type_arguments = | 588 const AbstractTypeArguments& instantiator_type_arguments = |
| 587 AbstractTypeArguments::CheckedHandle(arguments.At(3)); | 589 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(3)); |
| 588 const SubtypeTestCache& cache = | 590 const SubtypeTestCache& cache = |
| 589 SubtypeTestCache::CheckedHandle(arguments.At(4)); | 591 SubtypeTestCache::CheckedHandle(arguments.ArgAt(4)); |
| 590 ASSERT(type.IsFinalized()); | 592 ASSERT(type.IsFinalized()); |
| 591 Error& malformed_error = Error::Handle(); | 593 Error& malformed_error = Error::Handle(); |
| 592 const Bool& result = Bool::Handle( | 594 const Bool& result = Bool::Handle( |
| 593 instance.IsInstanceOf(type, | 595 instance.IsInstanceOf(type, |
| 594 instantiator_type_arguments, | 596 instantiator_type_arguments, |
| 595 &malformed_error) ? | 597 &malformed_error) ? |
| 596 Bool::True() : Bool::False()); | 598 Bool::True() : Bool::False()); |
| 597 if (FLAG_trace_type_checks) { | 599 if (FLAG_trace_type_checks) { |
| 598 PrintTypeCheck("InstanceOf", | 600 PrintTypeCheck("InstanceOf", |
| 599 instance, type, instantiator_type_arguments, result); | 601 instance, type, instantiator_type_arguments, result); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 617 // Check that the type of the given instance is a subtype of the given type and | 619 // Check that the type of the given instance is a subtype of the given type and |
| 618 // can therefore be assigned. | 620 // can therefore be assigned. |
| 619 // Arg0: instance being assigned. | 621 // Arg0: instance being assigned. |
| 620 // Arg1: type being assigned to. | 622 // Arg1: type being assigned to. |
| 621 // Arg2: instantiator (or null). | 623 // Arg2: instantiator (or null). |
| 622 // Arg3: type arguments of the instantiator of the type being assigned to. | 624 // Arg3: type arguments of the instantiator of the type being assigned to. |
| 623 // Arg4: name of variable being assigned to. | 625 // Arg4: name of variable being assigned to. |
| 624 // Arg5: SubtypeTestCache. | 626 // Arg5: SubtypeTestCache. |
| 625 // Return value: instance if a subtype, otherwise throw a TypeError. | 627 // Return value: instance if a subtype, otherwise throw a TypeError. |
| 626 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) { | 628 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) { |
| 627 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); | 629 ASSERT(arguments.ArgCount() == kTypeCheckRuntimeEntry.argument_count()); |
| 628 const Instance& src_instance = Instance::CheckedHandle(arguments.At(0)); | 630 const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 629 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(1)); | 631 const AbstractType& dst_type = |
| 630 const Instance& dst_instantiator = Instance::CheckedHandle(arguments.At(2)); | 632 AbstractType::CheckedHandle(arguments.ArgAt(1)); |
| 633 const Instance& dst_instantiator = |
| 634 Instance::CheckedHandle(arguments.ArgAt(2)); |
| 631 const AbstractTypeArguments& instantiator_type_arguments = | 635 const AbstractTypeArguments& instantiator_type_arguments = |
| 632 AbstractTypeArguments::CheckedHandle(arguments.At(3)); | 636 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(3)); |
| 633 const String& dst_name = String::CheckedHandle(arguments.At(4)); | 637 const String& dst_name = String::CheckedHandle(arguments.ArgAt(4)); |
| 634 const SubtypeTestCache& cache = | 638 const SubtypeTestCache& cache = |
| 635 SubtypeTestCache::CheckedHandle(arguments.At(5)); | 639 SubtypeTestCache::CheckedHandle(arguments.ArgAt(5)); |
| 636 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. | 640 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. |
| 637 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. | 641 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. |
| 638 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. | 642 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. |
| 639 | 643 |
| 640 Error& malformed_error = Error::Handle(); | 644 Error& malformed_error = Error::Handle(); |
| 641 const bool is_instance_of = src_instance.IsInstanceOf( | 645 const bool is_instance_of = src_instance.IsInstanceOf( |
| 642 dst_type, instantiator_type_arguments, &malformed_error); | 646 dst_type, instantiator_type_arguments, &malformed_error); |
| 643 | 647 |
| 644 if (FLAG_trace_type_checks) { | 648 if (FLAG_trace_type_checks) { |
| 645 PrintTypeCheck("TypeCheck", | 649 PrintTypeCheck("TypeCheck", |
| (...skipping 29 matching lines...) Expand all Loading... |
| 675 arguments.SetReturn(src_instance); | 679 arguments.SetReturn(src_instance); |
| 676 } | 680 } |
| 677 | 681 |
| 678 | 682 |
| 679 // Test whether a formal parameter was defined by a passed-in argument. | 683 // Test whether a formal parameter was defined by a passed-in argument. |
| 680 // Arg0: formal parameter index as Smi. | 684 // Arg0: formal parameter index as Smi. |
| 681 // Arg1: formal parameter name as Symbol. | 685 // Arg1: formal parameter name as Symbol. |
| 682 // Arg2: arguments descriptor array. | 686 // Arg2: arguments descriptor array. |
| 683 // Return value: true or false. | 687 // Return value: true or false. |
| 684 DEFINE_RUNTIME_ENTRY(ArgumentDefinitionTest, 3) { | 688 DEFINE_RUNTIME_ENTRY(ArgumentDefinitionTest, 3) { |
| 685 ASSERT(arguments.Count() == | 689 ASSERT(arguments.ArgCount() == |
| 686 kArgumentDefinitionTestRuntimeEntry.argument_count()); | 690 kArgumentDefinitionTestRuntimeEntry.argument_count()); |
| 687 const Smi& param_index = Smi::CheckedHandle(arguments.At(0)); | 691 const Smi& param_index = Smi::CheckedHandle(arguments.ArgAt(0)); |
| 688 const String& param_name = String::CheckedHandle(arguments.At(1)); | 692 const String& param_name = String::CheckedHandle(arguments.ArgAt(1)); |
| 689 ASSERT(param_name.IsSymbol()); | 693 ASSERT(param_name.IsSymbol()); |
| 690 const Array& arg_desc = Array::CheckedHandle(arguments.At(2)); | 694 const Array& arg_desc = Array::CheckedHandle(arguments.ArgAt(2)); |
| 691 const intptr_t num_pos_args = Smi::CheckedHandle(arg_desc.At(1)).Value(); | 695 const intptr_t num_pos_args = Smi::CheckedHandle(arg_desc.At(1)).Value(); |
| 692 // Check if the formal parameter is defined by a positional argument. | 696 // Check if the formal parameter is defined by a positional argument. |
| 693 bool is_defined = num_pos_args > param_index.Value(); | 697 bool is_defined = num_pos_args > param_index.Value(); |
| 694 if (!is_defined) { | 698 if (!is_defined) { |
| 695 // Check if the formal parameter is defined by a named argument. | 699 // Check if the formal parameter is defined by a named argument. |
| 696 const intptr_t num_named_args = | 700 const intptr_t num_named_args = |
| 697 Smi::CheckedHandle(arg_desc.At(0)).Value() - num_pos_args; | 701 Smi::CheckedHandle(arg_desc.At(0)).Value() - num_pos_args; |
| 698 String& arg_name = String::Handle(); | 702 String& arg_name = String::Handle(); |
| 699 for (intptr_t i = 0; i < num_named_args; i++) { | 703 for (intptr_t i = 0; i < num_named_args; i++) { |
| 700 arg_name ^= arg_desc.At(2*i + 2); | 704 arg_name ^= arg_desc.At(2*i + 2); |
| 701 if (arg_name.raw() == param_name.raw()) { | 705 if (arg_name.raw() == param_name.raw()) { |
| 702 is_defined = true; | 706 is_defined = true; |
| 703 break; | 707 break; |
| 704 } | 708 } |
| 705 } | 709 } |
| 706 } | 710 } |
| 707 arguments.SetReturn(Bool::Handle(Bool::Get(is_defined))); | 711 arguments.SetReturn(Bool::Handle(Bool::Get(is_defined))); |
| 708 } | 712 } |
| 709 | 713 |
| 710 | 714 |
| 711 // Report that the type of the given object is not bool in conditional context. | 715 // Report that the type of the given object is not bool in conditional context. |
| 712 // Arg0: bad object. | 716 // Arg0: bad object. |
| 713 // Return value: none, throws a TypeError. | 717 // Return value: none, throws a TypeError. |
| 714 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) { | 718 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) { |
| 715 ASSERT(arguments.Count() == | 719 ASSERT(arguments.ArgCount() == |
| 716 kConditionTypeErrorRuntimeEntry.argument_count()); | 720 kConditionTypeErrorRuntimeEntry.argument_count()); |
| 717 const intptr_t location = GetCallerLocation(); | 721 const intptr_t location = GetCallerLocation(); |
| 718 const Instance& src_instance = Instance::CheckedHandle(arguments.At(0)); | 722 const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 719 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); | 723 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); |
| 720 const Type& bool_interface = Type::Handle(Type::BoolType()); | 724 const Type& bool_interface = Type::Handle(Type::BoolType()); |
| 721 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); | 725 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); |
| 722 const String& src_type_name = String::Handle(src_type.UserVisibleName()); | 726 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 723 const String& bool_type_name = | 727 const String& bool_type_name = |
| 724 String::Handle(bool_interface.UserVisibleName()); | 728 String::Handle(bool_interface.UserVisibleName()); |
| 725 const String& expr = String::Handle(Symbols::New("boolean expression")); | 729 const String& expr = String::Handle(Symbols::New("boolean expression")); |
| 726 const String& no_malformed_type_error = String::Handle(); | 730 const String& no_malformed_type_error = String::Handle(); |
| 727 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, | 731 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, |
| 728 expr, no_malformed_type_error); | 732 expr, no_malformed_type_error); |
| 729 UNREACHABLE(); | 733 UNREACHABLE(); |
| 730 } | 734 } |
| 731 | 735 |
| 732 | 736 |
| 733 // Report that the type of the type check is malformed. | 737 // Report that the type of the type check is malformed. |
| 734 // Arg0: src value. | 738 // Arg0: src value. |
| 735 // Arg1: name of instance being assigned to. | 739 // Arg1: name of instance being assigned to. |
| 736 // Arg2: malformed type error message. | 740 // Arg2: malformed type error message. |
| 737 // Return value: none, throws an exception. | 741 // Return value: none, throws an exception. |
| 738 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { | 742 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { |
| 739 ASSERT(arguments.Count() == | 743 ASSERT(arguments.ArgCount() == |
| 740 kMalformedTypeErrorRuntimeEntry.argument_count()); | 744 kMalformedTypeErrorRuntimeEntry.argument_count()); |
| 741 const intptr_t location = GetCallerLocation(); | 745 const intptr_t location = GetCallerLocation(); |
| 742 const Instance& src_value = Instance::CheckedHandle(arguments.At(0)); | 746 const Instance& src_value = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 743 const String& dst_name = String::CheckedHandle(arguments.At(1)); | 747 const String& dst_name = String::CheckedHandle(arguments.ArgAt(1)); |
| 744 const String& malformed_error = String::CheckedHandle(arguments.At(2)); | 748 const String& malformed_error = String::CheckedHandle(arguments.ArgAt(2)); |
| 745 const String& dst_type_name = String::Handle(Symbols::New("malformed")); | 749 const String& dst_type_name = String::Handle(Symbols::New("malformed")); |
| 746 const AbstractType& src_type = AbstractType::Handle(src_value.GetType()); | 750 const AbstractType& src_type = AbstractType::Handle(src_value.GetType()); |
| 747 const String& src_type_name = String::Handle(src_type.UserVisibleName()); | 751 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 748 Exceptions::CreateAndThrowTypeError(location, src_type_name, | 752 Exceptions::CreateAndThrowTypeError(location, src_type_name, |
| 749 dst_type_name, dst_name, malformed_error); | 753 dst_type_name, dst_name, malformed_error); |
| 750 UNREACHABLE(); | 754 UNREACHABLE(); |
| 751 } | 755 } |
| 752 | 756 |
| 753 | 757 |
| 754 DEFINE_RUNTIME_ENTRY(Throw, 1) { | 758 DEFINE_RUNTIME_ENTRY(Throw, 1) { |
| 755 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); | 759 ASSERT(arguments.ArgCount() == kThrowRuntimeEntry.argument_count()); |
| 756 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); | 760 const Instance& exception = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 757 Exceptions::Throw(exception); | 761 Exceptions::Throw(exception); |
| 758 } | 762 } |
| 759 | 763 |
| 760 | 764 |
| 761 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { | 765 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { |
| 762 ASSERT(arguments.Count() == kReThrowRuntimeEntry.argument_count()); | 766 ASSERT(arguments.ArgCount() == kReThrowRuntimeEntry.argument_count()); |
| 763 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); | 767 const Instance& exception = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 764 const Instance& stacktrace = Instance::CheckedHandle(arguments.At(1)); | 768 const Instance& stacktrace = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 765 Exceptions::ReThrow(exception, stacktrace); | 769 Exceptions::ReThrow(exception, stacktrace); |
| 766 } | 770 } |
| 767 | 771 |
| 768 | 772 |
| 769 static bool UpdateResolvedStaticCall(const Code& code, | 773 static bool UpdateResolvedStaticCall(const Code& code, |
| 770 intptr_t offset, | 774 intptr_t offset, |
| 771 const Code& target_code) { | 775 const Code& target_code) { |
| 772 // PC offsets are mapped to the corresponding code object in the | 776 // PC offsets are mapped to the corresponding code object in the |
| 773 // resolved_static_calls array. The array grows as static calls are being | 777 // resolved_static_calls array. The array grows as static calls are being |
| 774 // resolved. | 778 // resolved. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 802 // Overwrite the currently recorded target. | 806 // Overwrite the currently recorded target. |
| 803 resolved_static_calls.SetAt(index + kCode, target_code); | 807 resolved_static_calls.SetAt(index + kCode, target_code); |
| 804 } | 808 } |
| 805 return index != -1; | 809 return index != -1; |
| 806 } | 810 } |
| 807 | 811 |
| 808 | 812 |
| 809 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { | 813 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { |
| 810 // This function is called after successful resolving and compilation of | 814 // This function is called after successful resolving and compilation of |
| 811 // the target method. | 815 // the target method. |
| 812 ASSERT(arguments.Count() == kPatchStaticCallRuntimeEntry.argument_count()); | 816 ASSERT(arguments.ArgCount() == kPatchStaticCallRuntimeEntry.argument_count()); |
| 813 DartFrameIterator iterator; | 817 DartFrameIterator iterator; |
| 814 StackFrame* caller_frame = iterator.NextFrame(); | 818 StackFrame* caller_frame = iterator.NextFrame(); |
| 815 ASSERT(caller_frame != NULL); | 819 ASSERT(caller_frame != NULL); |
| 816 uword target = 0; | 820 uword target = 0; |
| 817 Function& target_function = Function::Handle(); | 821 Function& target_function = Function::Handle(); |
| 818 CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target); | 822 CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target); |
| 819 ASSERT(target_function.HasCode()); | 823 ASSERT(target_function.HasCode()); |
| 820 const Code& target_code = Code::Handle(target_function.CurrentCode()); | 824 const Code& target_code = Code::Handle(target_function.CurrentCode()); |
| 821 uword new_target = target_code.EntryPoint(); | 825 uword new_target = target_code.EntryPoint(); |
| 822 // Verify that we are not patching repeatedly. | 826 // Verify that we are not patching repeatedly. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 } | 887 } |
| 884 | 888 |
| 885 | 889 |
| 886 // Resolves an instance function and compiles it if necessary. | 890 // Resolves an instance function and compiles it if necessary. |
| 887 // Arg0: receiver object. | 891 // Arg0: receiver object. |
| 888 // Returns: RawCode object or NULL (method not found or not compileable). | 892 // Returns: RawCode object or NULL (method not found or not compileable). |
| 889 // This is called by the megamorphic stub when instance call does not need to be | 893 // This is called by the megamorphic stub when instance call does not need to be |
| 890 // patched. | 894 // patched. |
| 891 // Used by megamorphic lookup/no-such-method-handling. | 895 // Used by megamorphic lookup/no-such-method-handling. |
| 892 DEFINE_RUNTIME_ENTRY(ResolveCompileInstanceFunction, 1) { | 896 DEFINE_RUNTIME_ENTRY(ResolveCompileInstanceFunction, 1) { |
| 893 ASSERT(arguments.Count() == | 897 ASSERT(arguments.ArgCount() == |
| 894 kResolveCompileInstanceFunctionRuntimeEntry.argument_count()); | 898 kResolveCompileInstanceFunctionRuntimeEntry.argument_count()); |
| 895 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 899 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 896 const Code& code = Code::Handle( | 900 const Code& code = Code::Handle( |
| 897 ResolveCompileInstanceCallTarget(isolate, receiver)); | 901 ResolveCompileInstanceCallTarget(isolate, receiver)); |
| 898 arguments.SetReturn(code); | 902 arguments.SetReturn(code); |
| 899 } | 903 } |
| 900 | 904 |
| 901 | 905 |
| 902 // Gets called from debug stub when code reaches a breakpoint. | 906 // Gets called from debug stub when code reaches a breakpoint. |
| 903 // Arg0: function object of the static function that was about to be called. | 907 // Arg0: function object of the static function that was about to be called. |
| 904 DEFINE_RUNTIME_ENTRY(BreakpointStaticHandler, 1) { | 908 DEFINE_RUNTIME_ENTRY(BreakpointStaticHandler, 1) { |
| 905 ASSERT(arguments.Count() == | 909 ASSERT(arguments.ArgCount() == |
| 906 kBreakpointStaticHandlerRuntimeEntry.argument_count()); | 910 kBreakpointStaticHandlerRuntimeEntry.argument_count()); |
| 907 ASSERT(isolate->debugger() != NULL); | 911 ASSERT(isolate->debugger() != NULL); |
| 908 isolate->debugger()->SignalBpReached(); | 912 isolate->debugger()->SignalBpReached(); |
| 909 // Make sure the static function that is about to be called is | 913 // Make sure the static function that is about to be called is |
| 910 // compiled. The stub will jump to the entry point without any | 914 // compiled. The stub will jump to the entry point without any |
| 911 // further tests. | 915 // further tests. |
| 912 const Function& function = Function::CheckedHandle(arguments.At(0)); | 916 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 913 if (!function.HasCode()) { | 917 if (!function.HasCode()) { |
| 914 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 918 const Error& error = Error::Handle(Compiler::CompileFunction(function)); |
| 915 if (!error.IsNull()) { | 919 if (!error.IsNull()) { |
| 916 Exceptions::PropagateError(error); | 920 Exceptions::PropagateError(error); |
| 917 } | 921 } |
| 918 } | 922 } |
| 919 } | 923 } |
| 920 | 924 |
| 921 | 925 |
| 922 // Gets called from debug stub when code reaches a breakpoint at a return | 926 // Gets called from debug stub when code reaches a breakpoint at a return |
| 923 // in Dart code. | 927 // in Dart code. |
| 924 DEFINE_RUNTIME_ENTRY(BreakpointReturnHandler, 0) { | 928 DEFINE_RUNTIME_ENTRY(BreakpointReturnHandler, 0) { |
| 925 ASSERT(arguments.Count() == | 929 ASSERT(arguments.ArgCount() == |
| 926 kBreakpointReturnHandlerRuntimeEntry.argument_count()); | 930 kBreakpointReturnHandlerRuntimeEntry.argument_count()); |
| 927 ASSERT(isolate->debugger() != NULL); | 931 ASSERT(isolate->debugger() != NULL); |
| 928 isolate->debugger()->SignalBpReached(); | 932 isolate->debugger()->SignalBpReached(); |
| 929 } | 933 } |
| 930 | 934 |
| 931 | 935 |
| 932 // Gets called from debug stub when code reaches a breakpoint. | 936 // Gets called from debug stub when code reaches a breakpoint. |
| 933 DEFINE_RUNTIME_ENTRY(BreakpointDynamicHandler, 0) { | 937 DEFINE_RUNTIME_ENTRY(BreakpointDynamicHandler, 0) { |
| 934 ASSERT(arguments.Count() == | 938 ASSERT(arguments.ArgCount() == |
| 935 kBreakpointDynamicHandlerRuntimeEntry.argument_count()); | 939 kBreakpointDynamicHandlerRuntimeEntry.argument_count()); |
| 936 ASSERT(isolate->debugger() != NULL); | 940 ASSERT(isolate->debugger() != NULL); |
| 937 isolate->debugger()->SignalBpReached(); | 941 isolate->debugger()->SignalBpReached(); |
| 938 } | 942 } |
| 939 | 943 |
| 940 | 944 |
| 941 static RawFunction* InlineCacheMissHandler( | 945 static RawFunction* InlineCacheMissHandler( |
| 942 Isolate* isolate, const GrowableArray<const Instance*>& args) { | 946 Isolate* isolate, const GrowableArray<const Instance*>& args) { |
| 943 const Instance& receiver = *args[0]; | 947 const Instance& receiver = *args[0]; |
| 944 const Code& target_code = | 948 const Code& target_code = |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 return target_function.raw(); | 995 return target_function.raw(); |
| 992 } | 996 } |
| 993 | 997 |
| 994 | 998 |
| 995 // Handles inline cache misses by updating the IC data array of the call | 999 // Handles inline cache misses by updating the IC data array of the call |
| 996 // site. | 1000 // site. |
| 997 // Arg0: Receiver object. | 1001 // Arg0: Receiver object. |
| 998 // Returns: target function with compiled code or null. | 1002 // Returns: target function with compiled code or null. |
| 999 // Modifies the instance call to hold the updated IC data array. | 1003 // Modifies the instance call to hold the updated IC data array. |
| 1000 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 1) { | 1004 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 1) { |
| 1001 ASSERT(arguments.Count() == | 1005 ASSERT(arguments.ArgCount() == |
| 1002 kInlineCacheMissHandlerOneArgRuntimeEntry.argument_count()); | 1006 kInlineCacheMissHandlerOneArgRuntimeEntry.argument_count()); |
| 1003 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 1007 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1004 GrowableArray<const Instance*> args(1); | 1008 GrowableArray<const Instance*> args(1); |
| 1005 args.Add(&receiver); | 1009 args.Add(&receiver); |
| 1006 const Function& result = | 1010 const Function& result = |
| 1007 Function::Handle(InlineCacheMissHandler(isolate, args)); | 1011 Function::Handle(InlineCacheMissHandler(isolate, args)); |
| 1008 arguments.SetReturn(result); | 1012 arguments.SetReturn(result); |
| 1009 } | 1013 } |
| 1010 | 1014 |
| 1011 | 1015 |
| 1012 // Handles inline cache misses by updating the IC data array of the call | 1016 // Handles inline cache misses by updating the IC data array of the call |
| 1013 // site. | 1017 // site. |
| 1014 // Arg0: Receiver object. | 1018 // Arg0: Receiver object. |
| 1015 // Arg1: Argument after receiver. | 1019 // Arg1: Argument after receiver. |
| 1016 // Returns: target function with compiled code or null. | 1020 // Returns: target function with compiled code or null. |
| 1017 // Modifies the instance call to hold the updated IC data array. | 1021 // Modifies the instance call to hold the updated IC data array. |
| 1018 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 2) { | 1022 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 2) { |
| 1019 ASSERT(arguments.Count() == | 1023 ASSERT(arguments.ArgCount() == |
| 1020 kInlineCacheMissHandlerTwoArgsRuntimeEntry.argument_count()); | 1024 kInlineCacheMissHandlerTwoArgsRuntimeEntry.argument_count()); |
| 1021 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 1025 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1022 const Instance& other = Instance::CheckedHandle(arguments.At(1)); | 1026 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 1023 GrowableArray<const Instance*> args(2); | 1027 GrowableArray<const Instance*> args(2); |
| 1024 args.Add(&receiver); | 1028 args.Add(&receiver); |
| 1025 args.Add(&other); | 1029 args.Add(&other); |
| 1026 const Function& result = | 1030 const Function& result = |
| 1027 Function::Handle(InlineCacheMissHandler(isolate, args)); | 1031 Function::Handle(InlineCacheMissHandler(isolate, args)); |
| 1028 arguments.SetReturn(result); | 1032 arguments.SetReturn(result); |
| 1029 } | 1033 } |
| 1030 | 1034 |
| 1031 | 1035 |
| 1032 // Handles inline cache misses by updating the IC data array of the call | 1036 // Handles inline cache misses by updating the IC data array of the call |
| 1033 // site. | 1037 // site. |
| 1034 // Arg0: Receiver object. | 1038 // Arg0: Receiver object. |
| 1035 // Arg1: Argument after receiver. | 1039 // Arg1: Argument after receiver. |
| 1036 // Arg2: Second argument after receiver. | 1040 // Arg2: Second argument after receiver. |
| 1037 // Returns: target function with compiled code or null. | 1041 // Returns: target function with compiled code or null. |
| 1038 // Modifies the instance call to hold the updated IC data array. | 1042 // Modifies the instance call to hold the updated IC data array. |
| 1039 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs, 3) { | 1043 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs, 3) { |
| 1040 ASSERT(arguments.Count() == | 1044 ASSERT(arguments.ArgCount() == |
| 1041 kInlineCacheMissHandlerThreeArgsRuntimeEntry.argument_count()); | 1045 kInlineCacheMissHandlerThreeArgsRuntimeEntry.argument_count()); |
| 1042 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 1046 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1043 const Instance& arg1 = Instance::CheckedHandle(arguments.At(1)); | 1047 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 1044 const Instance& arg2 = Instance::CheckedHandle(arguments.At(2)); | 1048 const Instance& arg2 = Instance::CheckedHandle(arguments.ArgAt(2)); |
| 1045 GrowableArray<const Instance*> args(3); | 1049 GrowableArray<const Instance*> args(3); |
| 1046 args.Add(&receiver); | 1050 args.Add(&receiver); |
| 1047 args.Add(&arg1); | 1051 args.Add(&arg1); |
| 1048 args.Add(&arg2); | 1052 args.Add(&arg2); |
| 1049 const Function& result = | 1053 const Function& result = |
| 1050 Function::Handle(InlineCacheMissHandler(isolate, args)); | 1054 Function::Handle(InlineCacheMissHandler(isolate, args)); |
| 1051 arguments.SetReturn(result); | 1055 arguments.SetReturn(result); |
| 1052 } | 1056 } |
| 1053 | 1057 |
| 1054 | 1058 |
| 1055 // Updates IC data for two arguments. Used by the equality operation when | 1059 // Updates IC data for two arguments. Used by the equality operation when |
| 1056 // the control flow bypasses regular inline cache (null arguments). | 1060 // the control flow bypasses regular inline cache (null arguments). |
| 1057 // Arg0: Receiver object. | 1061 // Arg0: Receiver object. |
| 1058 // Arg1: Argument after receiver. | 1062 // Arg1: Argument after receiver. |
| 1059 // Arg2: Target's name. | 1063 // Arg2: Target's name. |
| 1060 // Arg3: ICData. | 1064 // Arg3: ICData. |
| 1061 DEFINE_RUNTIME_ENTRY(UpdateICDataTwoArgs, 4) { | 1065 DEFINE_RUNTIME_ENTRY(UpdateICDataTwoArgs, 4) { |
| 1062 ASSERT(arguments.Count() == | 1066 ASSERT(arguments.ArgCount() == |
| 1063 kUpdateICDataTwoArgsRuntimeEntry.argument_count()); | 1067 kUpdateICDataTwoArgsRuntimeEntry.argument_count()); |
| 1064 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 1068 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1065 const Instance& arg1 = Instance::CheckedHandle(arguments.At(1)); | 1069 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 1066 const String& target_name = String::CheckedHandle(arguments.At(2)); | 1070 const String& target_name = String::CheckedHandle(arguments.ArgAt(2)); |
| 1067 const ICData& ic_data = ICData::CheckedHandle(arguments.At(3)); | 1071 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(3)); |
| 1068 GrowableArray<const Instance*> args(2); | 1072 GrowableArray<const Instance*> args(2); |
| 1069 args.Add(&receiver); | 1073 args.Add(&receiver); |
| 1070 args.Add(&arg1); | 1074 args.Add(&arg1); |
| 1071 const intptr_t kNumArguments = 2; | 1075 const intptr_t kNumArguments = 2; |
| 1072 const intptr_t kNumNamedArguments = 0; | 1076 const intptr_t kNumNamedArguments = 0; |
| 1073 Function& target_function = Function::Handle(); | 1077 Function& target_function = Function::Handle(); |
| 1074 target_function = Resolver::ResolveDynamic(receiver, | 1078 target_function = Resolver::ResolveDynamic(receiver, |
| 1075 target_name, | 1079 target_name, |
| 1076 kNumArguments, | 1080 kNumArguments, |
| 1077 kNumNamedArguments); | 1081 kNumNamedArguments); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 | 1113 |
| 1110 | 1114 |
| 1111 // Resolve an implicit closure by checking if an instance function | 1115 // Resolve an implicit closure by checking if an instance function |
| 1112 // of the same name exists and creating a closure object of the function. | 1116 // of the same name exists and creating a closure object of the function. |
| 1113 // Arg0: receiver object. | 1117 // Arg0: receiver object. |
| 1114 // Arg1: ic-data. | 1118 // Arg1: ic-data. |
| 1115 // Returns: Closure object or NULL (instance function not found). | 1119 // Returns: Closure object or NULL (instance function not found). |
| 1116 // This is called by the megamorphic stub when it is unable to resolve an | 1120 // This is called by the megamorphic stub when it is unable to resolve an |
| 1117 // instance method. This is done just before the call to noSuchMethod. | 1121 // instance method. This is done just before the call to noSuchMethod. |
| 1118 DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureFunction, 2) { | 1122 DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureFunction, 2) { |
| 1119 ASSERT(arguments.Count() == | 1123 ASSERT(arguments.ArgCount() == |
| 1120 kResolveImplicitClosureFunctionRuntimeEntry.argument_count()); | 1124 kResolveImplicitClosureFunctionRuntimeEntry.argument_count()); |
| 1121 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 1125 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1122 const ICData& ic_data = ICData::CheckedHandle(arguments.At(1)); | 1126 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 1123 const String& original_function_name = String::Handle(ic_data.target_name()); | 1127 const String& original_function_name = String::Handle(ic_data.target_name()); |
| 1124 Instance& closure = Instance::Handle(); | 1128 Instance& closure = Instance::Handle(); |
| 1125 if (!Field::IsGetterName(original_function_name)) { | 1129 if (!Field::IsGetterName(original_function_name)) { |
| 1126 // This is not a getter so can't be the case where we are trying to | 1130 // This is not a getter so can't be the case where we are trying to |
| 1127 // create an implicit closure of an instance function. | 1131 // create an implicit closure of an instance function. |
| 1128 arguments.SetReturn(closure); | 1132 arguments.SetReturn(closure); |
| 1129 return; | 1133 return; |
| 1130 } | 1134 } |
| 1131 const Class& receiver_class = Class::Handle(receiver.clazz()); | 1135 const Class& receiver_class = Class::Handle(receiver.clazz()); |
| 1132 ASSERT(!receiver_class.IsNull()); | 1136 ASSERT(!receiver_class.IsNull()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1157 | 1161 |
| 1158 | 1162 |
| 1159 // Resolve an implicit closure by invoking getter and checking if the return | 1163 // Resolve an implicit closure by invoking getter and checking if the return |
| 1160 // value from getter is a closure. | 1164 // value from getter is a closure. |
| 1161 // Arg0: receiver object. | 1165 // Arg0: receiver object. |
| 1162 // Arg1: ic-data. | 1166 // Arg1: ic-data. |
| 1163 // Returns: Closure object or NULL (closure not found). | 1167 // Returns: Closure object or NULL (closure not found). |
| 1164 // This is called by the megamorphic stub when it is unable to resolve an | 1168 // This is called by the megamorphic stub when it is unable to resolve an |
| 1165 // instance method. This is done just before the call to noSuchMethod. | 1169 // instance method. This is done just before the call to noSuchMethod. |
| 1166 DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureThroughGetter, 2) { | 1170 DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureThroughGetter, 2) { |
| 1167 ASSERT(arguments.Count() == | 1171 ASSERT(arguments.ArgCount() == |
| 1168 kResolveImplicitClosureThroughGetterRuntimeEntry.argument_count()); | 1172 kResolveImplicitClosureThroughGetterRuntimeEntry.argument_count()); |
| 1169 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 1173 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1170 const ICData& ic_data = ICData::CheckedHandle(arguments.At(1)); | 1174 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 1171 const String& original_function_name = String::Handle(ic_data.target_name()); | 1175 const String& original_function_name = String::Handle(ic_data.target_name()); |
| 1172 const int kNumArguments = 1; | 1176 const int kNumArguments = 1; |
| 1173 const int kNumNamedArguments = 0; | 1177 const int kNumNamedArguments = 0; |
| 1174 const String& getter_function_name = | 1178 const String& getter_function_name = |
| 1175 String::Handle(Field::GetterName(original_function_name)); | 1179 String::Handle(Field::GetterName(original_function_name)); |
| 1176 Function& function = Function::ZoneHandle( | 1180 Function& function = Function::ZoneHandle( |
| 1177 Resolver::ResolveDynamic(receiver, | 1181 Resolver::ResolveDynamic(receiver, |
| 1178 getter_function_name, | 1182 getter_function_name, |
| 1179 kNumArguments, | 1183 kNumArguments, |
| 1180 kNumNamedArguments)); | 1184 kNumNamedArguments)); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); | 1253 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); |
| 1250 UNREACHABLE(); | 1254 UNREACHABLE(); |
| 1251 } | 1255 } |
| 1252 | 1256 |
| 1253 | 1257 |
| 1254 // Invoke Implicit Closure function. | 1258 // Invoke Implicit Closure function. |
| 1255 // Arg0: closure object. | 1259 // Arg0: closure object. |
| 1256 // Arg1: arguments descriptor (originally passed as dart instance invocation). | 1260 // Arg1: arguments descriptor (originally passed as dart instance invocation). |
| 1257 // Arg2: arguments array (originally passed to dart instance invocation). | 1261 // Arg2: arguments array (originally passed to dart instance invocation). |
| 1258 DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) { | 1262 DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) { |
| 1259 ASSERT(arguments.Count() == | 1263 ASSERT(arguments.ArgCount() == |
| 1260 kInvokeImplicitClosureFunctionRuntimeEntry.argument_count()); | 1264 kInvokeImplicitClosureFunctionRuntimeEntry.argument_count()); |
| 1261 const Instance& closure = Instance::CheckedHandle(arguments.At(0)); | 1265 const Instance& closure = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1262 const Array& arg_descriptor = Array::CheckedHandle(arguments.At(1)); | 1266 const Array& arg_descriptor = Array::CheckedHandle(arguments.ArgAt(1)); |
| 1263 const Array& func_arguments = Array::CheckedHandle(arguments.At(2)); | 1267 const Array& func_arguments = Array::CheckedHandle(arguments.ArgAt(2)); |
| 1264 const Function& function = Function::Handle(Closure::function(closure)); | 1268 const Function& function = Function::Handle(Closure::function(closure)); |
| 1265 ASSERT(!function.IsNull()); | 1269 ASSERT(!function.IsNull()); |
| 1266 if (!function.HasCode()) { | 1270 if (!function.HasCode()) { |
| 1267 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 1271 const Error& error = Error::Handle(Compiler::CompileFunction(function)); |
| 1268 if (!error.IsNull()) { | 1272 if (!error.IsNull()) { |
| 1269 Exceptions::PropagateError(error); | 1273 Exceptions::PropagateError(error); |
| 1270 } | 1274 } |
| 1271 } | 1275 } |
| 1272 const Context& context = Context::Handle(Closure::context(closure)); | 1276 const Context& context = Context::Handle(Closure::context(closure)); |
| 1273 const Code& code = Code::Handle(function.CurrentCode()); | 1277 const Code& code = Code::Handle(function.CurrentCode()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1299 arguments.SetReturn(result); | 1303 arguments.SetReturn(result); |
| 1300 } | 1304 } |
| 1301 | 1305 |
| 1302 | 1306 |
| 1303 // Invoke appropriate noSuchMethod function. | 1307 // Invoke appropriate noSuchMethod function. |
| 1304 // Arg0: receiver. | 1308 // Arg0: receiver. |
| 1305 // Arg1: ic-data. | 1309 // Arg1: ic-data. |
| 1306 // Arg2: original arguments descriptor array. | 1310 // Arg2: original arguments descriptor array. |
| 1307 // Arg3: original arguments array. | 1311 // Arg3: original arguments array. |
| 1308 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { | 1312 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { |
| 1309 ASSERT(arguments.Count() == | 1313 ASSERT(arguments.ArgCount() == |
| 1310 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count()); | 1314 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count()); |
| 1311 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 1315 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1312 const ICData& ic_data = ICData::CheckedHandle(arguments.At(1)); | 1316 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 1313 const String& original_function_name = String::Handle(ic_data.target_name()); | 1317 const String& original_function_name = String::Handle(ic_data.target_name()); |
| 1314 ASSERT(!Array::CheckedHandle(arguments.At(2)).IsNull()); | 1318 ASSERT(!Array::CheckedHandle(arguments.ArgAt(2)).IsNull()); |
| 1315 const Array& orig_arguments = Array::CheckedHandle(arguments.At(3)); | 1319 const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3)); |
| 1316 // Allocate an InvocationMirror object. | 1320 // Allocate an InvocationMirror object. |
| 1317 // TODO(regis): Fill in the InvocationMirror object correctly at | 1321 // TODO(regis): Fill in the InvocationMirror object correctly at |
| 1318 // this point we do not deal with named arguments and treat them | 1322 // this point we do not deal with named arguments and treat them |
| 1319 // all as positional. | 1323 // all as positional. |
| 1320 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 1324 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1321 const String& invocation_mirror_name = String::Handle( | 1325 const String& invocation_mirror_name = String::Handle( |
| 1322 Symbols::InvocationMirror()); | 1326 Symbols::InvocationMirror()); |
| 1323 Class& invocation_mirror_class = Class::Handle( | 1327 Class& invocation_mirror_class = Class::Handle( |
| 1324 core_lib.LookupClassAllowPrivate(invocation_mirror_name)); | 1328 core_lib.LookupClassAllowPrivate(invocation_mirror_name)); |
| 1325 ASSERT(!invocation_mirror_class.IsNull()); | 1329 ASSERT(!invocation_mirror_class.IsNull()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1359 arguments.SetReturn(result); | 1363 arguments.SetReturn(result); |
| 1360 } | 1364 } |
| 1361 | 1365 |
| 1362 | 1366 |
| 1363 // A non-closure object was invoked as a closure, so call the "call" method | 1367 // A non-closure object was invoked as a closure, so call the "call" method |
| 1364 // on it. | 1368 // on it. |
| 1365 // Arg0: non-closure object. | 1369 // Arg0: non-closure object. |
| 1366 // Arg1: arguments array. | 1370 // Arg1: arguments array. |
| 1367 // TODO(regis): Rename this entry? | 1371 // TODO(regis): Rename this entry? |
| 1368 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) { | 1372 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) { |
| 1369 ASSERT(arguments.Count() == | 1373 ASSERT(arguments.ArgCount() == |
| 1370 kReportObjectNotClosureRuntimeEntry.argument_count()); | 1374 kReportObjectNotClosureRuntimeEntry.argument_count()); |
| 1371 const Instance& instance = Instance::CheckedHandle(arguments.At(0)); | 1375 const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1372 const Array& function_args = Array::CheckedHandle(arguments.At(1)); | 1376 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(1)); |
| 1373 const String& function_name = String::Handle(Symbols::Call()); | 1377 const String& function_name = String::Handle(Symbols::Call()); |
| 1374 GrowableArray<const Object*> dart_arguments(5); | 1378 GrowableArray<const Object*> dart_arguments(5); |
| 1375 if (instance.IsNull()) { | 1379 if (instance.IsNull()) { |
| 1376 dart_arguments.Add(&function_name); | 1380 dart_arguments.Add(&function_name); |
| 1377 dart_arguments.Add(&function_args); | 1381 dart_arguments.Add(&function_args); |
| 1378 Exceptions::ThrowByType(Exceptions::kNullPointer, dart_arguments); | 1382 Exceptions::ThrowByType(Exceptions::kNullPointer, dart_arguments); |
| 1379 UNREACHABLE(); | 1383 UNREACHABLE(); |
| 1380 } | 1384 } |
| 1381 | 1385 |
| 1382 // TODO(regis): Resolve and invoke "call" method, if existing. | 1386 // TODO(regis): Resolve and invoke "call" method, if existing. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1406 dart_arguments.Add(&array); | 1410 dart_arguments.Add(&array); |
| 1407 } | 1411 } |
| 1408 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); | 1412 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); |
| 1409 UNREACHABLE(); | 1413 UNREACHABLE(); |
| 1410 } | 1414 } |
| 1411 | 1415 |
| 1412 | 1416 |
| 1413 // A closure object was invoked with incompatible arguments. | 1417 // A closure object was invoked with incompatible arguments. |
| 1414 // TODO(regis): Deprecated. This case should be handled by a noSuchMethod call. | 1418 // TODO(regis): Deprecated. This case should be handled by a noSuchMethod call. |
| 1415 DEFINE_RUNTIME_ENTRY(ClosureArgumentMismatch, 0) { | 1419 DEFINE_RUNTIME_ENTRY(ClosureArgumentMismatch, 0) { |
| 1416 ASSERT(arguments.Count() == | 1420 ASSERT(arguments.ArgCount() == |
| 1417 kClosureArgumentMismatchRuntimeEntry.argument_count()); | 1421 kClosureArgumentMismatchRuntimeEntry.argument_count()); |
| 1418 const Instance& instance = Instance::Handle(); // Incorrect. OK for now. | 1422 const Instance& instance = Instance::Handle(); // Incorrect. OK for now. |
| 1419 const Array& function_args = Array::Handle(); // Incorrect. OK for now. | 1423 const Array& function_args = Array::Handle(); // Incorrect. OK for now. |
| 1420 const String& function_name = String::Handle(Symbols::Call()); | 1424 const String& function_name = String::Handle(Symbols::Call()); |
| 1421 GrowableArray<const Object*> dart_arguments(5); | 1425 GrowableArray<const Object*> dart_arguments(5); |
| 1422 | 1426 |
| 1423 const Object& null_object = Object::Handle(); | 1427 const Object& null_object = Object::Handle(); |
| 1424 dart_arguments.Add(&instance); | 1428 dart_arguments.Add(&instance); |
| 1425 dart_arguments.Add(&function_name); | 1429 dart_arguments.Add(&function_name); |
| 1426 dart_arguments.Add(&function_args); | 1430 dart_arguments.Add(&function_args); |
| 1427 dart_arguments.Add(&null_object); | 1431 dart_arguments.Add(&null_object); |
| 1428 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); | 1432 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); |
| 1429 UNREACHABLE(); | 1433 UNREACHABLE(); |
| 1430 } | 1434 } |
| 1431 | 1435 |
| 1432 | 1436 |
| 1433 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { | 1437 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { |
| 1434 ASSERT(arguments.Count() == | 1438 ASSERT(arguments.ArgCount() == |
| 1435 kStackOverflowRuntimeEntry.argument_count()); | 1439 kStackOverflowRuntimeEntry.argument_count()); |
| 1436 uword stack_pos = reinterpret_cast<uword>(&arguments); | 1440 uword stack_pos = reinterpret_cast<uword>(&arguments); |
| 1437 | 1441 |
| 1438 // If an interrupt happens at the same time as a stack overflow, we | 1442 // If an interrupt happens at the same time as a stack overflow, we |
| 1439 // process the stack overflow first. | 1443 // process the stack overflow first. |
| 1440 if (stack_pos < isolate->saved_stack_limit()) { | 1444 if (stack_pos < isolate->saved_stack_limit()) { |
| 1441 // Use the preallocated stack overflow exception to avoid calling | 1445 // Use the preallocated stack overflow exception to avoid calling |
| 1442 // into dart code. | 1446 // into dart code. |
| 1443 const Instance& exception = | 1447 const Instance& exception = |
| 1444 Instance::Handle(isolate->object_store()->stack_overflow()); | 1448 Instance::Handle(isolate->object_store()->stack_overflow()); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1487 caller_frame->LookupDartFunction()); | 1491 caller_frame->LookupDartFunction()); |
| 1488 const Code& code = Code::Handle(caller_frame->LookupDartCode()); | 1492 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
| 1489 OS::Print(" -> caller: %s (%s)\n", | 1493 OS::Print(" -> caller: %s (%s)\n", |
| 1490 caller_function.ToFullyQualifiedCString(), | 1494 caller_function.ToFullyQualifiedCString(), |
| 1491 code.is_optimized() ? "optimized" : "unoptimized"); | 1495 code.is_optimized() ? "optimized" : "unoptimized"); |
| 1492 } | 1496 } |
| 1493 } | 1497 } |
| 1494 | 1498 |
| 1495 | 1499 |
| 1496 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { | 1500 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { |
| 1497 ASSERT(arguments.Count() == | 1501 ASSERT(arguments.ArgCount() == |
| 1498 kTraceICCallRuntimeEntry.argument_count()); | 1502 kTraceICCallRuntimeEntry.argument_count()); |
| 1499 const ICData& ic_data = ICData::CheckedHandle(arguments.At(0)); | 1503 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); |
| 1500 const Function& function = Function::CheckedHandle(arguments.At(1)); | 1504 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); |
| 1501 DartFrameIterator iterator; | 1505 DartFrameIterator iterator; |
| 1502 StackFrame* frame = iterator.NextFrame(); | 1506 StackFrame* frame = iterator.NextFrame(); |
| 1503 ASSERT(frame != NULL); | 1507 ASSERT(frame != NULL); |
| 1504 OS::Print("IC call @%#"Px": ICData: %p cnt:%"Pd" nchecks: %"Pd" %s %s\n", | 1508 OS::Print("IC call @%#"Px": ICData: %p cnt:%"Pd" nchecks: %"Pd" %s %s\n", |
| 1505 frame->pc(), | 1509 frame->pc(), |
| 1506 ic_data.raw(), | 1510 ic_data.raw(), |
| 1507 function.usage_counter(), | 1511 function.usage_counter(), |
| 1508 ic_data.NumberOfChecks(), | 1512 ic_data.NumberOfChecks(), |
| 1509 ic_data.is_closure_call() ? "closure" : "", | 1513 ic_data.is_closure_call() ? "closure" : "", |
| 1510 function.ToFullyQualifiedCString()); | 1514 function.ToFullyQualifiedCString()); |
| 1511 } | 1515 } |
| 1512 | 1516 |
| 1513 | 1517 |
| 1514 // This is called from function that needs to be optimized. | 1518 // This is called from function that needs to be optimized. |
| 1515 // The requesting function can be already optimized (reoptimization). | 1519 // The requesting function can be already optimized (reoptimization). |
| 1516 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { | 1520 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { |
| 1517 ASSERT(arguments.Count() == | 1521 ASSERT(arguments.ArgCount() == |
| 1518 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); | 1522 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); |
| 1519 const intptr_t kLowInvocationCount = -100000000; | 1523 const intptr_t kLowInvocationCount = -100000000; |
| 1520 const Function& function = Function::CheckedHandle(arguments.At(0)); | 1524 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 1521 if (isolate->debugger()->IsActive()) { | 1525 if (isolate->debugger()->IsActive()) { |
| 1522 // We cannot set breakpoints in optimized code, so do not optimize | 1526 // We cannot set breakpoints in optimized code, so do not optimize |
| 1523 // the function. | 1527 // the function. |
| 1524 function.set_usage_counter(0); | 1528 function.set_usage_counter(0); |
| 1525 return; | 1529 return; |
| 1526 } | 1530 } |
| 1527 if (function.deoptimization_counter() >= | 1531 if (function.deoptimization_counter() >= |
| 1528 FLAG_deoptimization_counter_threshold) { | 1532 FLAG_deoptimization_counter_threshold) { |
| 1529 if (FLAG_trace_failed_optimization_attempts) { | 1533 if (FLAG_trace_failed_optimization_attempts) { |
| 1530 PrintCaller("Too Many Deoptimizations"); | 1534 PrintCaller("Too Many Deoptimizations"); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1556 } | 1560 } |
| 1557 // TODO(5442338): Abort as this should not happen. | 1561 // TODO(5442338): Abort as this should not happen. |
| 1558 function.set_usage_counter(kLowInvocationCount); | 1562 function.set_usage_counter(kLowInvocationCount); |
| 1559 } | 1563 } |
| 1560 } | 1564 } |
| 1561 | 1565 |
| 1562 | 1566 |
| 1563 // The caller must be a static call in a Dart frame, or an entry frame. | 1567 // The caller must be a static call in a Dart frame, or an entry frame. |
| 1564 // Patch static call to point to 'new_entry_point'. | 1568 // Patch static call to point to 'new_entry_point'. |
| 1565 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 1) { | 1569 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 1) { |
| 1566 ASSERT(arguments.Count() == kFixCallersTargetRuntimeEntry.argument_count()); | 1570 ASSERT(arguments.ArgCount() == |
| 1567 const Function& function = Function::CheckedHandle(arguments.At(0)); | 1571 kFixCallersTargetRuntimeEntry.argument_count()); |
| 1572 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 1568 ASSERT(!function.IsNull()); | 1573 ASSERT(!function.IsNull()); |
| 1569 ASSERT(function.HasCode()); | 1574 ASSERT(function.HasCode()); |
| 1570 | 1575 |
| 1571 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); | 1576 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); |
| 1572 StackFrame* frame = iterator.NextFrame(); | 1577 StackFrame* frame = iterator.NextFrame(); |
| 1573 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { | 1578 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { |
| 1574 frame = iterator.NextFrame(); | 1579 frame = iterator.NextFrame(); |
| 1575 } | 1580 } |
| 1576 ASSERT(frame != NULL); | 1581 ASSERT(frame != NULL); |
| 1577 if (!frame->IsEntryFrame()) { | 1582 if (!frame->IsEntryFrame()) { |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1907 intptr_t line, column; | 1912 intptr_t line, column; |
| 1908 script.GetTokenLocation(token_pos, &line, &column); | 1913 script.GetTokenLocation(token_pos, &line, &column); |
| 1909 String& line_string = String::Handle(script.GetLine(line)); | 1914 String& line_string = String::Handle(script.GetLine(line)); |
| 1910 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1915 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
| 1911 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1916 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
| 1912 } | 1917 } |
| 1913 } | 1918 } |
| 1914 | 1919 |
| 1915 | 1920 |
| 1916 } // namespace dart | 1921 } // namespace dart |
| OLD | NEW |