| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/code_generator.h" | 5 #include "vm/code_generator.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
| 9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 DECLARE_FLAG(int, deoptimization_counter_threshold); | 55 DECLARE_FLAG(int, deoptimization_counter_threshold); |
| 56 DECLARE_FLAG(bool, enable_type_checks); | 56 DECLARE_FLAG(bool, enable_type_checks); |
| 57 DECLARE_FLAG(bool, report_usage_count); | 57 DECLARE_FLAG(bool, report_usage_count); |
| 58 DECLARE_FLAG(bool, trace_type_checks); | 58 DECLARE_FLAG(bool, trace_type_checks); |
| 59 | 59 |
| 60 DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement."); | 60 DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement."); |
| 61 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement."); | 61 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement."); |
| 62 | 62 |
| 63 | 63 |
| 64 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { | 64 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { |
| 65 ASSERT(arguments.ArgCount() == | |
| 66 kTraceFunctionEntryRuntimeEntry.argument_count()); | |
| 67 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 65 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 68 const String& function_name = String::Handle(function.name()); | 66 const String& function_name = String::Handle(function.name()); |
| 69 const String& class_name = | 67 const String& class_name = |
| 70 String::Handle(Class::Handle(function.Owner()).Name()); | 68 String::Handle(Class::Handle(function.Owner()).Name()); |
| 71 OS::PrintErr("> Entering '%s.%s'\n", | 69 OS::PrintErr("> Entering '%s.%s'\n", |
| 72 class_name.ToCString(), function_name.ToCString()); | 70 class_name.ToCString(), function_name.ToCString()); |
| 73 } | 71 } |
| 74 | 72 |
| 75 | 73 |
| 76 DEFINE_RUNTIME_ENTRY(TraceFunctionExit, 1) { | 74 DEFINE_RUNTIME_ENTRY(TraceFunctionExit, 1) { |
| 77 ASSERT(arguments.ArgCount() == | |
| 78 kTraceFunctionExitRuntimeEntry.argument_count()); | |
| 79 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 75 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 80 const String& function_name = String::Handle(function.name()); | 76 const String& function_name = String::Handle(function.name()); |
| 81 const String& class_name = | 77 const String& class_name = |
| 82 String::Handle(Class::Handle(function.Owner()).Name()); | 78 String::Handle(Class::Handle(function.Owner()).Name()); |
| 83 OS::PrintErr("< Exiting '%s.%s'\n", | 79 OS::PrintErr("< Exiting '%s.%s'\n", |
| 84 class_name.ToCString(), function_name.ToCString()); | 80 class_name.ToCString(), function_name.ToCString()); |
| 85 } | 81 } |
| 86 | 82 |
| 87 | 83 |
| 88 // Allocation of a fixed length array of given element type. | 84 // Allocation of a fixed length array of given element type. |
| 89 // This runtime entry is never called for allocating a List of a generic type, | 85 // This runtime entry is never called for allocating a List of a generic type, |
| 90 // because a prior run time call instantiates the element type if necessary. | 86 // because a prior run time call instantiates the element type if necessary. |
| 91 // Arg0: array length. | 87 // Arg0: array length. |
| 92 // Arg1: array type arguments, i.e. vector of 1 type, the element type. | 88 // Arg1: array type arguments, i.e. vector of 1 type, the element type. |
| 93 // Return value: newly allocated array of length arg0. | 89 // Return value: newly allocated array of length arg0. |
| 94 DEFINE_RUNTIME_ENTRY(AllocateArray, 2) { | 90 DEFINE_RUNTIME_ENTRY(AllocateArray, 2) { |
| 95 ASSERT(arguments.ArgCount() == kAllocateArrayRuntimeEntry.argument_count()); | |
| 96 const Smi& length = Smi::CheckedHandle(arguments.ArgAt(0)); | 91 const Smi& length = Smi::CheckedHandle(arguments.ArgAt(0)); |
| 97 const Array& array = Array::Handle(Array::New(length.Value())); | 92 const Array& array = Array::Handle(Array::New(length.Value())); |
| 98 arguments.SetReturn(array); | 93 arguments.SetReturn(array); |
| 99 AbstractTypeArguments& element_type = | 94 AbstractTypeArguments& element_type = |
| 100 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); | 95 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 101 // An Array is raw or takes one type argument. However, its type argument | 96 // An Array is raw or takes one type argument. However, its type argument |
| 102 // vector may be longer than 1 due to a type optimization reusing the type | 97 // vector may be longer than 1 due to a type optimization reusing the type |
| 103 // argument vector of the instantiator. | 98 // argument vector of the instantiator. |
| 104 ASSERT(element_type.IsNull() || | 99 ASSERT(element_type.IsNull() || |
| 105 ((element_type.Length() >= 1) && element_type.IsInstantiated())); | 100 ((element_type.Length() >= 1) && element_type.IsInstantiated())); |
| 106 array.SetTypeArguments(element_type); // May be null. | 101 array.SetTypeArguments(element_type); // May be null. |
| 107 } | 102 } |
| 108 | 103 |
| 109 | 104 |
| 110 // Allocate a new object. | 105 // Allocate a new object. |
| 111 // Arg0: class of the object that needs to be allocated. | 106 // Arg0: class of the object that needs to be allocated. |
| 112 // Arg1: type arguments of the object that needs to be allocated. | 107 // Arg1: type arguments of the object that needs to be allocated. |
| 113 // Arg2: type arguments of the instantiator or kNoInstantiator. | 108 // Arg2: type arguments of the instantiator or kNoInstantiator. |
| 114 // Return value: newly allocated object. | 109 // Return value: newly allocated object. |
| 115 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) { | 110 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) { |
| 116 ASSERT(arguments.ArgCount() == kAllocateObjectRuntimeEntry.argument_count()); | |
| 117 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); | 111 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); |
| 118 const Instance& instance = Instance::Handle(Instance::New(cls)); | 112 const Instance& instance = Instance::Handle(Instance::New(cls)); |
| 119 arguments.SetReturn(instance); | 113 arguments.SetReturn(instance); |
| 120 if (!cls.HasTypeArguments()) { | 114 if (!cls.HasTypeArguments()) { |
| 121 // No type arguments required for a non-parameterized type. | 115 // No type arguments required for a non-parameterized type. |
| 122 ASSERT(Instance::CheckedHandle(arguments.ArgAt(1)).IsNull()); | 116 ASSERT(Instance::CheckedHandle(arguments.ArgAt(1)).IsNull()); |
| 123 return; | 117 return; |
| 124 } | 118 } |
| 125 AbstractTypeArguments& type_arguments = | 119 AbstractTypeArguments& type_arguments = |
| 126 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); | 120 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 | 155 |
| 162 | 156 |
| 163 // Allocate a new object of a generic type and check that the instantiated type | 157 // Allocate a new object of a generic type and check that the instantiated type |
| 164 // arguments are within the declared bounds or throw a dynamic type error. | 158 // arguments are within the declared bounds or throw a dynamic type error. |
| 165 // Arg0: class of the object that needs to be allocated. | 159 // Arg0: class of the object that needs to be allocated. |
| 166 // Arg1: type arguments of the object that needs to be allocated. | 160 // Arg1: type arguments of the object that needs to be allocated. |
| 167 // Arg2: type arguments of the instantiator or kNoInstantiator. | 161 // Arg2: type arguments of the instantiator or kNoInstantiator. |
| 168 // Return value: newly allocated object. | 162 // Return value: newly allocated object. |
| 169 DEFINE_RUNTIME_ENTRY(AllocateObjectWithBoundsCheck, 3) { | 163 DEFINE_RUNTIME_ENTRY(AllocateObjectWithBoundsCheck, 3) { |
| 170 ASSERT(FLAG_enable_type_checks); | 164 ASSERT(FLAG_enable_type_checks); |
| 171 ASSERT(arguments.ArgCount() == | |
| 172 kAllocateObjectWithBoundsCheckRuntimeEntry.argument_count()); | |
| 173 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); | 165 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); |
| 174 const Instance& instance = Instance::Handle(Instance::New(cls)); | 166 const Instance& instance = Instance::Handle(Instance::New(cls)); |
| 175 arguments.SetReturn(instance); | 167 arguments.SetReturn(instance); |
| 176 ASSERT(cls.HasTypeArguments()); | 168 ASSERT(cls.HasTypeArguments()); |
| 177 AbstractTypeArguments& type_arguments = | 169 AbstractTypeArguments& type_arguments = |
| 178 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); | 170 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 179 if (Object::Handle(arguments.ArgAt(2)).IsSmi()) { | 171 if (Object::Handle(arguments.ArgAt(2)).IsSmi()) { |
| 180 ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() == | 172 ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() == |
| 181 StubCode::kNoInstantiator); | 173 StubCode::kNoInstantiator); |
| 182 // Unless null (for a raw type), the type argument vector may be longer than | 174 // Unless null (for a raw type), the type argument vector may be longer than |
| (...skipping 29 matching lines...) Expand all Loading... |
| 212 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); | 204 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); |
| 213 instance.SetTypeArguments(type_arguments); | 205 instance.SetTypeArguments(type_arguments); |
| 214 } | 206 } |
| 215 | 207 |
| 216 | 208 |
| 217 // Instantiate type. | 209 // Instantiate type. |
| 218 // Arg0: uninstantiated type. | 210 // Arg0: uninstantiated type. |
| 219 // Arg1: instantiator type arguments. | 211 // Arg1: instantiator type arguments. |
| 220 // Return value: instantiated type. | 212 // Return value: instantiated type. |
| 221 DEFINE_RUNTIME_ENTRY(InstantiateType, 2) { | 213 DEFINE_RUNTIME_ENTRY(InstantiateType, 2) { |
| 222 ASSERT(arguments.ArgCount() == kInstantiateTypeRuntimeEntry.argument_count()); | |
| 223 AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(0)); | 214 AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(0)); |
| 224 const AbstractTypeArguments& instantiator = | 215 const AbstractTypeArguments& instantiator = |
| 225 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); | 216 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 226 ASSERT(!type.IsNull() && !type.IsInstantiated()); | 217 ASSERT(!type.IsNull() && !type.IsInstantiated()); |
| 227 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); | 218 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); |
| 228 Error& malformed_error = Error::Handle(); | 219 Error& malformed_error = Error::Handle(); |
| 229 type = type.InstantiateFrom(instantiator, &malformed_error); | 220 type = type.InstantiateFrom(instantiator, &malformed_error); |
| 230 if (!malformed_error.IsNull()) { | 221 if (!malformed_error.IsNull()) { |
| 231 // Throw a dynamic type error. | 222 // Throw a dynamic type error. |
| 232 const intptr_t location = GetCallerLocation(); | 223 const intptr_t location = GetCallerLocation(); |
| 233 String& malformed_error_message = String::Handle( | 224 String& malformed_error_message = String::Handle( |
| 234 String::New(malformed_error.ToErrorCString())); | 225 String::New(malformed_error.ToErrorCString())); |
| 235 Exceptions::CreateAndThrowTypeError( | 226 Exceptions::CreateAndThrowTypeError( |
| 236 location, Symbols::Empty(), Symbols::Empty(), | 227 location, Symbols::Empty(), Symbols::Empty(), |
| 237 Symbols::Empty(), malformed_error_message); | 228 Symbols::Empty(), malformed_error_message); |
| 238 UNREACHABLE(); | 229 UNREACHABLE(); |
| 239 } | 230 } |
| 240 ASSERT(!type.IsNull() && type.IsInstantiated()); | 231 ASSERT(!type.IsNull() && type.IsInstantiated()); |
| 241 arguments.SetReturn(type); | 232 arguments.SetReturn(type); |
| 242 } | 233 } |
| 243 | 234 |
| 244 | 235 |
| 245 // Instantiate type arguments. | 236 // Instantiate type arguments. |
| 246 // Arg0: uninstantiated type arguments. | 237 // Arg0: uninstantiated type arguments. |
| 247 // Arg1: instantiator type arguments. | 238 // Arg1: instantiator type arguments. |
| 248 // Return value: instantiated type arguments. | 239 // Return value: instantiated type arguments. |
| 249 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { | 240 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { |
| 250 ASSERT(arguments.ArgCount() == | |
| 251 kInstantiateTypeArgumentsRuntimeEntry.argument_count()); | |
| 252 AbstractTypeArguments& type_arguments = | 241 AbstractTypeArguments& type_arguments = |
| 253 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(0)); | 242 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(0)); |
| 254 const AbstractTypeArguments& instantiator = | 243 const AbstractTypeArguments& instantiator = |
| 255 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); | 244 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 256 ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated()); | 245 ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated()); |
| 257 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); | 246 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); |
| 258 // Code inlined in the caller should have optimized the case where the | 247 // Code inlined in the caller should have optimized the case where the |
| 259 // instantiator can be reused as type argument vector. | 248 // instantiator can be reused as type argument vector. |
| 260 ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity()); | 249 ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity()); |
| 261 type_arguments = InstantiatedTypeArguments::New(type_arguments, instantiator); | 250 type_arguments = InstantiatedTypeArguments::New(type_arguments, instantiator); |
| 262 ASSERT(type_arguments.IsInstantiated()); | 251 ASSERT(type_arguments.IsInstantiated()); |
| 263 arguments.SetReturn(type_arguments); | 252 arguments.SetReturn(type_arguments); |
| 264 } | 253 } |
| 265 | 254 |
| 266 | 255 |
| 267 // Allocate a new closure. | 256 // Allocate a new closure. |
| 268 // The type argument vector of a closure is always the vector of type parameters | 257 // The type argument vector of a closure is always the vector of type parameters |
| 269 // of its signature class, i.e. an uninstantiated identity vector. Therefore, | 258 // of its signature class, i.e. an uninstantiated identity vector. Therefore, |
| 270 // the instantiator type arguments can be used as the instantiated closure type | 259 // the instantiator type arguments can be used as the instantiated closure type |
| 271 // arguments and is passed here as the type arguments. | 260 // arguments and is passed here as the type arguments. |
| 272 // Arg0: local function. | 261 // Arg0: local function. |
| 273 // Arg1: type arguments of the closure (i.e. instantiator). | 262 // Arg1: type arguments of the closure (i.e. instantiator). |
| 274 // Return value: newly allocated closure. | 263 // Return value: newly allocated closure. |
| 275 DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) { | 264 DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) { |
| 276 ASSERT(arguments.ArgCount() == kAllocateClosureRuntimeEntry.argument_count()); | |
| 277 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 265 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 278 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction()); | 266 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction()); |
| 279 const AbstractTypeArguments& type_arguments = | 267 const AbstractTypeArguments& type_arguments = |
| 280 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); | 268 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 281 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); | 269 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); |
| 282 // The current context was saved in the Isolate structure when entering the | 270 // The current context was saved in the Isolate structure when entering the |
| 283 // runtime. | 271 // runtime. |
| 284 const Context& context = Context::Handle(isolate->top_context()); | 272 const Context& context = Context::Handle(isolate->top_context()); |
| 285 ASSERT(!context.IsNull()); | 273 ASSERT(!context.IsNull()); |
| 286 const Instance& closure = Instance::Handle(Closure::New(function, context)); | 274 const Instance& closure = Instance::Handle(Closure::New(function, context)); |
| 287 Closure::SetTypeArguments(closure, type_arguments); | 275 Closure::SetTypeArguments(closure, type_arguments); |
| 288 arguments.SetReturn(closure); | 276 arguments.SetReturn(closure); |
| 289 } | 277 } |
| 290 | 278 |
| 291 | 279 |
| 292 // Allocate a new implicit instance closure. | 280 // Allocate a new implicit instance closure. |
| 293 // Arg0: local function. | 281 // Arg0: local function. |
| 294 // Arg1: receiver object. | 282 // Arg1: receiver object. |
| 295 // Arg2: type arguments of the closure. | 283 // Arg2: type arguments of the closure. |
| 296 // Return value: newly allocated closure. | 284 // Return value: newly allocated closure. |
| 297 DEFINE_RUNTIME_ENTRY(AllocateImplicitInstanceClosure, 3) { | 285 DEFINE_RUNTIME_ENTRY(AllocateImplicitInstanceClosure, 3) { |
| 298 ASSERT(arguments.ArgCount() == | |
| 299 kAllocateImplicitInstanceClosureRuntimeEntry.argument_count()); | |
| 300 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 286 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 301 ASSERT(function.IsImplicitInstanceClosureFunction()); | 287 ASSERT(function.IsImplicitInstanceClosureFunction()); |
| 302 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(1)); | 288 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 303 const AbstractTypeArguments& type_arguments = | 289 const AbstractTypeArguments& type_arguments = |
| 304 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(2)); | 290 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(2)); |
| 305 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); | 291 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); |
| 306 Context& context = Context::Handle(); | 292 Context& context = Context::Handle(); |
| 307 context = Context::New(1); | 293 context = Context::New(1); |
| 308 context.SetAt(0, receiver); | 294 context.SetAt(0, receiver); |
| 309 const Instance& closure = Instance::Handle(Closure::New(function, context)); | 295 const Instance& closure = Instance::Handle(Closure::New(function, context)); |
| 310 Closure::SetTypeArguments(closure, type_arguments); | 296 Closure::SetTypeArguments(closure, type_arguments); |
| 311 arguments.SetReturn(closure); | 297 arguments.SetReturn(closure); |
| 312 } | 298 } |
| 313 | 299 |
| 314 | 300 |
| 315 // Allocate a new context large enough to hold the given number of variables. | 301 // Allocate a new context large enough to hold the given number of variables. |
| 316 // Arg0: number of variables. | 302 // Arg0: number of variables. |
| 317 // Return value: newly allocated context. | 303 // Return value: newly allocated context. |
| 318 DEFINE_RUNTIME_ENTRY(AllocateContext, 1) { | 304 DEFINE_RUNTIME_ENTRY(AllocateContext, 1) { |
| 319 ASSERT(arguments.ArgCount() == kAllocateContextRuntimeEntry.argument_count()); | |
| 320 const Smi& num_variables = Smi::CheckedHandle(arguments.ArgAt(0)); | 305 const Smi& num_variables = Smi::CheckedHandle(arguments.ArgAt(0)); |
| 321 arguments.SetReturn(Context::Handle(Context::New(num_variables.Value()))); | 306 arguments.SetReturn(Context::Handle(Context::New(num_variables.Value()))); |
| 322 } | 307 } |
| 323 | 308 |
| 324 | 309 |
| 325 // Make a copy of the given context, including the values of the captured | 310 // Make a copy of the given context, including the values of the captured |
| 326 // variables. | 311 // variables. |
| 327 // Arg0: the context to be cloned. | 312 // Arg0: the context to be cloned. |
| 328 // Return value: newly allocated context. | 313 // Return value: newly allocated context. |
| 329 DEFINE_RUNTIME_ENTRY(CloneContext, 1) { | 314 DEFINE_RUNTIME_ENTRY(CloneContext, 1) { |
| 330 ASSERT(arguments.ArgCount() == kCloneContextRuntimeEntry.argument_count()); | |
| 331 const Context& ctx = Context::CheckedHandle(arguments.ArgAt(0)); | 315 const Context& ctx = Context::CheckedHandle(arguments.ArgAt(0)); |
| 332 Context& cloned_ctx = Context::Handle(Context::New(ctx.num_variables())); | 316 Context& cloned_ctx = Context::Handle(Context::New(ctx.num_variables())); |
| 333 cloned_ctx.set_parent(Context::Handle(ctx.parent())); | 317 cloned_ctx.set_parent(Context::Handle(ctx.parent())); |
| 334 for (int i = 0; i < ctx.num_variables(); i++) { | 318 for (int i = 0; i < ctx.num_variables(); i++) { |
| 335 cloned_ctx.SetAt(i, Instance::Handle(ctx.At(i))); | 319 cloned_ctx.SetAt(i, Instance::Handle(ctx.At(i))); |
| 336 } | 320 } |
| 337 arguments.SetReturn(cloned_ctx); | 321 arguments.SetReturn(cloned_ctx); |
| 338 } | 322 } |
| 339 | 323 |
| 340 | 324 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 | 531 |
| 548 // Check that the given instance is an instance of the given type. | 532 // Check that the given instance is an instance of the given type. |
| 549 // Tested instance may not be null, because the null test is inlined. | 533 // Tested instance may not be null, because the null test is inlined. |
| 550 // Arg0: instance being checked. | 534 // Arg0: instance being checked. |
| 551 // Arg1: type. | 535 // Arg1: type. |
| 552 // Arg2: instantiator (or null). | 536 // Arg2: instantiator (or null). |
| 553 // Arg3: type arguments of the instantiator of the type. | 537 // Arg3: type arguments of the instantiator of the type. |
| 554 // Arg4: SubtypeTestCache. | 538 // Arg4: SubtypeTestCache. |
| 555 // Return value: true or false, or may throw a type error in checked mode. | 539 // Return value: true or false, or may throw a type error in checked mode. |
| 556 DEFINE_RUNTIME_ENTRY(Instanceof, 5) { | 540 DEFINE_RUNTIME_ENTRY(Instanceof, 5) { |
| 557 ASSERT(arguments.ArgCount() == kInstanceofRuntimeEntry.argument_count()); | |
| 558 const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0)); | 541 const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 559 const AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(1)); | 542 const AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(1)); |
| 560 const Instance& instantiator = Instance::CheckedHandle(arguments.ArgAt(2)); | 543 const Instance& instantiator = Instance::CheckedHandle(arguments.ArgAt(2)); |
| 561 const AbstractTypeArguments& instantiator_type_arguments = | 544 const AbstractTypeArguments& instantiator_type_arguments = |
| 562 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(3)); | 545 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(3)); |
| 563 const SubtypeTestCache& cache = | 546 const SubtypeTestCache& cache = |
| 564 SubtypeTestCache::CheckedHandle(arguments.ArgAt(4)); | 547 SubtypeTestCache::CheckedHandle(arguments.ArgAt(4)); |
| 565 ASSERT(type.IsFinalized()); | 548 ASSERT(type.IsFinalized()); |
| 566 Error& malformed_error = Error::Handle(); | 549 Error& malformed_error = Error::Handle(); |
| 567 const Bool& result = | 550 const Bool& result = |
| (...skipping 23 matching lines...) Expand all Loading... |
| 591 // Check that the type of the given instance is a subtype of the given type and | 574 // Check that the type of the given instance is a subtype of the given type and |
| 592 // can therefore be assigned. | 575 // can therefore be assigned. |
| 593 // Arg0: instance being assigned. | 576 // Arg0: instance being assigned. |
| 594 // Arg1: type being assigned to. | 577 // Arg1: type being assigned to. |
| 595 // Arg2: instantiator (or null). | 578 // Arg2: instantiator (or null). |
| 596 // Arg3: type arguments of the instantiator of the type being assigned to. | 579 // Arg3: type arguments of the instantiator of the type being assigned to. |
| 597 // Arg4: name of variable being assigned to. | 580 // Arg4: name of variable being assigned to. |
| 598 // Arg5: SubtypeTestCache. | 581 // Arg5: SubtypeTestCache. |
| 599 // Return value: instance if a subtype, otherwise throw a TypeError. | 582 // Return value: instance if a subtype, otherwise throw a TypeError. |
| 600 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) { | 583 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) { |
| 601 ASSERT(arguments.ArgCount() == kTypeCheckRuntimeEntry.argument_count()); | |
| 602 const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0)); | 584 const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 603 const AbstractType& dst_type = | 585 const AbstractType& dst_type = |
| 604 AbstractType::CheckedHandle(arguments.ArgAt(1)); | 586 AbstractType::CheckedHandle(arguments.ArgAt(1)); |
| 605 const Instance& dst_instantiator = | 587 const Instance& dst_instantiator = |
| 606 Instance::CheckedHandle(arguments.ArgAt(2)); | 588 Instance::CheckedHandle(arguments.ArgAt(2)); |
| 607 const AbstractTypeArguments& instantiator_type_arguments = | 589 const AbstractTypeArguments& instantiator_type_arguments = |
| 608 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(3)); | 590 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(3)); |
| 609 const String& dst_name = String::CheckedHandle(arguments.ArgAt(4)); | 591 const String& dst_name = String::CheckedHandle(arguments.ArgAt(4)); |
| 610 const SubtypeTestCache& cache = | 592 const SubtypeTestCache& cache = |
| 611 SubtypeTestCache::CheckedHandle(arguments.ArgAt(5)); | 593 SubtypeTestCache::CheckedHandle(arguments.ArgAt(5)); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 dst_instantiator, instantiator_type_arguments, | 633 dst_instantiator, instantiator_type_arguments, |
| 652 Bool::True(), cache); | 634 Bool::True(), cache); |
| 653 arguments.SetReturn(src_instance); | 635 arguments.SetReturn(src_instance); |
| 654 } | 636 } |
| 655 | 637 |
| 656 | 638 |
| 657 // Report that the type of the given object is not bool in conditional context. | 639 // Report that the type of the given object is not bool in conditional context. |
| 658 // Arg0: bad object. | 640 // Arg0: bad object. |
| 659 // Return value: none, throws a TypeError. | 641 // Return value: none, throws a TypeError. |
| 660 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) { | 642 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) { |
| 661 ASSERT(arguments.ArgCount() == | |
| 662 kConditionTypeErrorRuntimeEntry.argument_count()); | |
| 663 const intptr_t location = GetCallerLocation(); | 643 const intptr_t location = GetCallerLocation(); |
| 664 const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0)); | 644 const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 665 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); | 645 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); |
| 666 const Type& bool_interface = Type::Handle(Type::BoolType()); | 646 const Type& bool_interface = Type::Handle(Type::BoolType()); |
| 667 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); | 647 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); |
| 668 const String& src_type_name = String::Handle(src_type.UserVisibleName()); | 648 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 669 const String& bool_type_name = | 649 const String& bool_type_name = |
| 670 String::Handle(bool_interface.UserVisibleName()); | 650 String::Handle(bool_interface.UserVisibleName()); |
| 671 const String& no_malformed_type_error = String::Handle(); | 651 const String& no_malformed_type_error = String::Handle(); |
| 672 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, | 652 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, |
| 673 Symbols::BooleanExpression(), | 653 Symbols::BooleanExpression(), |
| 674 no_malformed_type_error); | 654 no_malformed_type_error); |
| 675 UNREACHABLE(); | 655 UNREACHABLE(); |
| 676 } | 656 } |
| 677 | 657 |
| 678 | 658 |
| 679 // Report that the type of the type check is malformed. | 659 // Report that the type of the type check is malformed. |
| 680 // Arg0: src value. | 660 // Arg0: src value. |
| 681 // Arg1: name of instance being assigned to. | 661 // Arg1: name of instance being assigned to. |
| 682 // Arg2: malformed type error message. | 662 // Arg2: malformed type error message. |
| 683 // Return value: none, throws an exception. | 663 // Return value: none, throws an exception. |
| 684 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { | 664 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { |
| 685 ASSERT(arguments.ArgCount() == | |
| 686 kMalformedTypeErrorRuntimeEntry.argument_count()); | |
| 687 const intptr_t location = GetCallerLocation(); | 665 const intptr_t location = GetCallerLocation(); |
| 688 const Instance& src_value = Instance::CheckedHandle(arguments.ArgAt(0)); | 666 const Instance& src_value = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 689 const String& dst_name = String::CheckedHandle(arguments.ArgAt(1)); | 667 const String& dst_name = String::CheckedHandle(arguments.ArgAt(1)); |
| 690 const String& malformed_error = String::CheckedHandle(arguments.ArgAt(2)); | 668 const String& malformed_error = String::CheckedHandle(arguments.ArgAt(2)); |
| 691 const AbstractType& src_type = AbstractType::Handle(src_value.GetType()); | 669 const AbstractType& src_type = AbstractType::Handle(src_value.GetType()); |
| 692 const String& src_type_name = String::Handle(src_type.UserVisibleName()); | 670 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 693 Exceptions::CreateAndThrowTypeError(location, src_type_name, | 671 Exceptions::CreateAndThrowTypeError(location, src_type_name, |
| 694 Symbols::Malformed(), | 672 Symbols::Malformed(), |
| 695 dst_name, malformed_error); | 673 dst_name, malformed_error); |
| 696 UNREACHABLE(); | 674 UNREACHABLE(); |
| 697 } | 675 } |
| 698 | 676 |
| 699 | 677 |
| 700 DEFINE_RUNTIME_ENTRY(Throw, 1) { | 678 DEFINE_RUNTIME_ENTRY(Throw, 1) { |
| 701 ASSERT(arguments.ArgCount() == kThrowRuntimeEntry.argument_count()); | |
| 702 const Instance& exception = Instance::CheckedHandle(arguments.ArgAt(0)); | 679 const Instance& exception = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 703 Exceptions::Throw(exception); | 680 Exceptions::Throw(exception); |
| 704 } | 681 } |
| 705 | 682 |
| 706 | 683 |
| 707 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { | 684 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { |
| 708 ASSERT(arguments.ArgCount() == kReThrowRuntimeEntry.argument_count()); | |
| 709 const Instance& exception = Instance::CheckedHandle(arguments.ArgAt(0)); | 685 const Instance& exception = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 710 const Instance& stacktrace = Instance::CheckedHandle(arguments.ArgAt(1)); | 686 const Instance& stacktrace = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 711 Exceptions::ReThrow(exception, stacktrace); | 687 Exceptions::ReThrow(exception, stacktrace); |
| 712 } | 688 } |
| 713 | 689 |
| 714 | 690 |
| 715 // Patches static call in optimized code with the target's entry point. | 691 // Patches static call in optimized code with the target's entry point. |
| 716 // Compiles target if necessary. | 692 // Compiles target if necessary. |
| 717 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { | 693 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { |
| 718 ASSERT(arguments.ArgCount() == kPatchStaticCallRuntimeEntry.argument_count()); | |
| 719 DartFrameIterator iterator; | 694 DartFrameIterator iterator; |
| 720 StackFrame* caller_frame = iterator.NextFrame(); | 695 StackFrame* caller_frame = iterator.NextFrame(); |
| 721 ASSERT(caller_frame != NULL); | 696 ASSERT(caller_frame != NULL); |
| 722 const Code& caller_code = Code::Handle(caller_frame->LookupDartCode()); | 697 const Code& caller_code = Code::Handle(caller_frame->LookupDartCode()); |
| 723 ASSERT(!caller_code.IsNull()); | 698 ASSERT(!caller_code.IsNull()); |
| 724 ASSERT(caller_code.is_optimized()); | 699 ASSERT(caller_code.is_optimized()); |
| 725 const Function& target_function = Function::Handle( | 700 const Function& target_function = Function::Handle( |
| 726 caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc())); | 701 caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc())); |
| 727 if (!target_function.HasCode()) { | 702 if (!target_function.HasCode()) { |
| 728 const Error& error = | 703 const Error& error = |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 static void CheckResultError(const Object& result) { | 757 static void CheckResultError(const Object& result) { |
| 783 if (result.IsError()) { | 758 if (result.IsError()) { |
| 784 Exceptions::PropagateError(Error::Cast(result)); | 759 Exceptions::PropagateError(Error::Cast(result)); |
| 785 } | 760 } |
| 786 } | 761 } |
| 787 | 762 |
| 788 | 763 |
| 789 // Gets called from debug stub when code reaches a breakpoint | 764 // Gets called from debug stub when code reaches a breakpoint |
| 790 // set on a runtime stub call. | 765 // set on a runtime stub call. |
| 791 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { | 766 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { |
| 792 ASSERT(arguments.ArgCount() == | |
| 793 kBreakpointRuntimeHandlerRuntimeEntry.argument_count()); | |
| 794 ASSERT(isolate->debugger() != NULL); | 767 ASSERT(isolate->debugger() != NULL); |
| 795 DartFrameIterator iterator; | 768 DartFrameIterator iterator; |
| 796 StackFrame* caller_frame = iterator.NextFrame(); | 769 StackFrame* caller_frame = iterator.NextFrame(); |
| 797 ASSERT(caller_frame != NULL); | 770 ASSERT(caller_frame != NULL); |
| 798 uword orig_stub = | 771 uword orig_stub = |
| 799 isolate->debugger()->GetPatchedStubAddress(caller_frame->pc()); | 772 isolate->debugger()->GetPatchedStubAddress(caller_frame->pc()); |
| 800 isolate->debugger()->SignalBpReached(); | 773 isolate->debugger()->SignalBpReached(); |
| 801 ASSERT((orig_stub & kSmiTagMask) == kSmiTag); | 774 ASSERT((orig_stub & kSmiTagMask) == kSmiTag); |
| 802 arguments.SetReturn(Smi::Handle(reinterpret_cast<RawSmi*>(orig_stub))); | 775 arguments.SetReturn(Smi::Handle(reinterpret_cast<RawSmi*>(orig_stub))); |
| 803 } | 776 } |
| 804 | 777 |
| 805 | 778 |
| 806 // Gets called from debug stub when code reaches a breakpoint. | 779 // Gets called from debug stub when code reaches a breakpoint. |
| 807 DEFINE_RUNTIME_ENTRY(BreakpointStaticHandler, 0) { | 780 DEFINE_RUNTIME_ENTRY(BreakpointStaticHandler, 0) { |
| 808 ASSERT(arguments.ArgCount() == | |
| 809 kBreakpointStaticHandlerRuntimeEntry.argument_count()); | |
| 810 ASSERT(isolate->debugger() != NULL); | 781 ASSERT(isolate->debugger() != NULL); |
| 811 isolate->debugger()->SignalBpReached(); | 782 isolate->debugger()->SignalBpReached(); |
| 812 // Make sure the static function that is about to be called is | 783 // Make sure the static function that is about to be called is |
| 813 // compiled. The stub will jump to the entry point without any | 784 // compiled. The stub will jump to the entry point without any |
| 814 // further tests. | 785 // further tests. |
| 815 DartFrameIterator iterator; | 786 DartFrameIterator iterator; |
| 816 StackFrame* caller_frame = iterator.NextFrame(); | 787 StackFrame* caller_frame = iterator.NextFrame(); |
| 817 ASSERT(caller_frame != NULL); | 788 ASSERT(caller_frame != NULL); |
| 818 const Code& code = Code::Handle(caller_frame->LookupDartCode()); | 789 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
| 819 ASSERT(!code.is_optimized()); | 790 ASSERT(!code.is_optimized()); |
| 820 const Function& function = | 791 const Function& function = |
| 821 Function::Handle(CodePatcher::GetUnoptimizedStaticCallAt( | 792 Function::Handle(CodePatcher::GetUnoptimizedStaticCallAt( |
| 822 caller_frame->pc(), code, NULL)); | 793 caller_frame->pc(), code, NULL)); |
| 823 | 794 |
| 824 if (!function.HasCode()) { | 795 if (!function.HasCode()) { |
| 825 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 796 const Error& error = Error::Handle(Compiler::CompileFunction(function)); |
| 826 if (!error.IsNull()) { | 797 if (!error.IsNull()) { |
| 827 Exceptions::PropagateError(error); | 798 Exceptions::PropagateError(error); |
| 828 } | 799 } |
| 829 } | 800 } |
| 830 arguments.SetReturn(Code::ZoneHandle(function.CurrentCode())); | 801 arguments.SetReturn(Code::ZoneHandle(function.CurrentCode())); |
| 831 } | 802 } |
| 832 | 803 |
| 833 | 804 |
| 834 // Gets called from debug stub when code reaches a breakpoint at a return | 805 // Gets called from debug stub when code reaches a breakpoint at a return |
| 835 // in Dart code. | 806 // in Dart code. |
| 836 DEFINE_RUNTIME_ENTRY(BreakpointReturnHandler, 0) { | 807 DEFINE_RUNTIME_ENTRY(BreakpointReturnHandler, 0) { |
| 837 ASSERT(arguments.ArgCount() == | |
| 838 kBreakpointReturnHandlerRuntimeEntry.argument_count()); | |
| 839 ASSERT(isolate->debugger() != NULL); | 808 ASSERT(isolate->debugger() != NULL); |
| 840 isolate->debugger()->SignalBpReached(); | 809 isolate->debugger()->SignalBpReached(); |
| 841 } | 810 } |
| 842 | 811 |
| 843 | 812 |
| 844 // Gets called from debug stub when code reaches a breakpoint. | 813 // Gets called from debug stub when code reaches a breakpoint. |
| 845 DEFINE_RUNTIME_ENTRY(BreakpointDynamicHandler, 0) { | 814 DEFINE_RUNTIME_ENTRY(BreakpointDynamicHandler, 0) { |
| 846 ASSERT(arguments.ArgCount() == | |
| 847 kBreakpointDynamicHandlerRuntimeEntry.argument_count()); | |
| 848 ASSERT(isolate->debugger() != NULL); | 815 ASSERT(isolate->debugger() != NULL); |
| 849 isolate->debugger()->SignalBpReached(); | 816 isolate->debugger()->SignalBpReached(); |
| 850 } | 817 } |
| 851 | 818 |
| 852 | 819 |
| 853 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) { | 820 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) { |
| 854 ASSERT(arguments.ArgCount() == | |
| 855 kSingleStepHandlerRuntimeEntry.argument_count()); | |
| 856 ASSERT(isolate->debugger() != NULL); | 821 ASSERT(isolate->debugger() != NULL); |
| 857 isolate->debugger()->SingleStepCallback(); | 822 isolate->debugger()->SingleStepCallback(); |
| 858 } | 823 } |
| 859 | 824 |
| 860 | 825 |
| 861 static RawFunction* InlineCacheMissHandler( | 826 static RawFunction* InlineCacheMissHandler( |
| 862 const GrowableArray<const Instance*>& args, | 827 const GrowableArray<const Instance*>& args, |
| 863 const ICData& ic_data) { | 828 const ICData& ic_data) { |
| 864 const Instance& receiver = *args[0]; | 829 const Instance& receiver = *args[0]; |
| 865 const Code& target_code = | 830 const Code& target_code = |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 } | 878 } |
| 914 | 879 |
| 915 | 880 |
| 916 // Handles inline cache misses by updating the IC data array of the call | 881 // Handles inline cache misses by updating the IC data array of the call |
| 917 // site. | 882 // site. |
| 918 // Arg0: Receiver object. | 883 // Arg0: Receiver object. |
| 919 // Arg1: IC data object. | 884 // Arg1: IC data object. |
| 920 // Returns: target function with compiled code or null. | 885 // Returns: target function with compiled code or null. |
| 921 // Modifies the instance call to hold the updated IC data array. | 886 // Modifies the instance call to hold the updated IC data array. |
| 922 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) { | 887 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) { |
| 923 ASSERT(arguments.ArgCount() == | |
| 924 kInlineCacheMissHandlerOneArgRuntimeEntry.argument_count()); | |
| 925 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 888 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 926 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 889 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 927 GrowableArray<const Instance*> args(1); | 890 GrowableArray<const Instance*> args(1); |
| 928 args.Add(&receiver); | 891 args.Add(&receiver); |
| 929 const Function& result = | 892 const Function& result = |
| 930 Function::Handle(InlineCacheMissHandler(args, ic_data)); | 893 Function::Handle(InlineCacheMissHandler(args, ic_data)); |
| 931 arguments.SetReturn(result); | 894 arguments.SetReturn(result); |
| 932 } | 895 } |
| 933 | 896 |
| 934 | 897 |
| 935 // Handles inline cache misses by updating the IC data array of the call | 898 // Handles inline cache misses by updating the IC data array of the call |
| 936 // site. | 899 // site. |
| 937 // Arg0: Receiver object. | 900 // Arg0: Receiver object. |
| 938 // Arg1: Argument after receiver. | 901 // Arg1: Argument after receiver. |
| 939 // Arg2: IC data object. | 902 // Arg2: IC data object. |
| 940 // Returns: target function with compiled code or null. | 903 // Returns: target function with compiled code or null. |
| 941 // Modifies the instance call to hold the updated IC data array. | 904 // Modifies the instance call to hold the updated IC data array. |
| 942 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 3) { | 905 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 3) { |
| 943 ASSERT(arguments.ArgCount() == | |
| 944 kInlineCacheMissHandlerTwoArgsRuntimeEntry.argument_count()); | |
| 945 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 906 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 946 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1)); | 907 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 947 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); | 908 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); |
| 948 GrowableArray<const Instance*> args(2); | 909 GrowableArray<const Instance*> args(2); |
| 949 args.Add(&receiver); | 910 args.Add(&receiver); |
| 950 args.Add(&other); | 911 args.Add(&other); |
| 951 const Function& result = | 912 const Function& result = |
| 952 Function::Handle(InlineCacheMissHandler(args, ic_data)); | 913 Function::Handle(InlineCacheMissHandler(args, ic_data)); |
| 953 arguments.SetReturn(result); | 914 arguments.SetReturn(result); |
| 954 } | 915 } |
| 955 | 916 |
| 956 | 917 |
| 957 // Handles inline cache misses by updating the IC data array of the call | 918 // Handles inline cache misses by updating the IC data array of the call |
| 958 // site. | 919 // site. |
| 959 // Arg0: Receiver object. | 920 // Arg0: Receiver object. |
| 960 // Arg1: Argument after receiver. | 921 // Arg1: Argument after receiver. |
| 961 // Arg2: Second argument after receiver. | 922 // Arg2: Second argument after receiver. |
| 962 // Arg3: IC data object. | 923 // Arg3: IC data object. |
| 963 // Returns: target function with compiled code or null. | 924 // Returns: target function with compiled code or null. |
| 964 // Modifies the instance call to hold the updated IC data array. | 925 // Modifies the instance call to hold the updated IC data array. |
| 965 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs, 4) { | 926 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs, 4) { |
| 966 ASSERT(arguments.ArgCount() == | |
| 967 kInlineCacheMissHandlerThreeArgsRuntimeEntry.argument_count()); | |
| 968 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 927 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 969 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); | 928 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 970 const Instance& arg2 = Instance::CheckedHandle(arguments.ArgAt(2)); | 929 const Instance& arg2 = Instance::CheckedHandle(arguments.ArgAt(2)); |
| 971 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(3)); | 930 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(3)); |
| 972 GrowableArray<const Instance*> args(3); | 931 GrowableArray<const Instance*> args(3); |
| 973 args.Add(&receiver); | 932 args.Add(&receiver); |
| 974 args.Add(&arg1); | 933 args.Add(&arg1); |
| 975 args.Add(&arg2); | 934 args.Add(&arg2); |
| 976 const Function& result = | 935 const Function& result = |
| 977 Function::Handle(InlineCacheMissHandler(args, ic_data)); | 936 Function::Handle(InlineCacheMissHandler(args, ic_data)); |
| 978 arguments.SetReturn(result); | 937 arguments.SetReturn(result); |
| 979 } | 938 } |
| 980 | 939 |
| 981 | 940 |
| 982 // Handles a static call in unoptimized code that has two argument types not | 941 // Handles a static call in unoptimized code that has two argument types not |
| 983 // seen before. Compile the target if necessary and update the ICData. | 942 // seen before. Compile the target if necessary and update the ICData. |
| 984 // Arg0: argument 0. | 943 // Arg0: argument 0. |
| 985 // Arg1: argument 1. | 944 // Arg1: argument 1. |
| 986 // Arg2: IC data object. | 945 // Arg2: IC data object. |
| 987 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) { | 946 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) { |
| 988 ASSERT(arguments.ArgCount() == | |
| 989 kStaticCallMissHandlerTwoArgsRuntimeEntry.argument_count()); | |
| 990 const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0)); | 947 const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 991 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); | 948 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 992 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); | 949 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); |
| 993 // IC data for static call is prepopulated with the statically known target. | 950 // IC data for static call is prepopulated with the statically known target. |
| 994 ASSERT(ic_data.NumberOfChecks() > 0); | 951 ASSERT(ic_data.NumberOfChecks() > 0); |
| 995 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); | 952 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); |
| 996 if (!target.HasCode()) { | 953 if (!target.HasCode()) { |
| 997 const Error& error = Error::Handle(Compiler::CompileFunction(target)); | 954 const Error& error = Error::Handle(Compiler::CompileFunction(target)); |
| 998 if (!error.IsNull()) { | 955 if (!error.IsNull()) { |
| 999 Exceptions::PropagateError(error); | 956 Exceptions::PropagateError(error); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1018 | 975 |
| 1019 // Handle a miss of a megamorphic cache. | 976 // Handle a miss of a megamorphic cache. |
| 1020 // Arg0: Receiver. | 977 // Arg0: Receiver. |
| 1021 // Arg1: ICData object. | 978 // Arg1: ICData object. |
| 1022 // Arg2: Arguments descriptor array. | 979 // Arg2: Arguments descriptor array. |
| 1023 | 980 |
| 1024 // Returns: target instructions to call or null if the | 981 // Returns: target instructions to call or null if the |
| 1025 // InstanceFunctionLookup stub should be used (e.g., to invoke no such | 982 // InstanceFunctionLookup stub should be used (e.g., to invoke no such |
| 1026 // method and implicit closures).. | 983 // method and implicit closures).. |
| 1027 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) { | 984 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) { |
| 1028 ASSERT(arguments.ArgCount() == | |
| 1029 kMegamorphicCacheMissHandlerRuntimeEntry.argument_count()); | |
| 1030 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 985 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1031 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 986 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 1032 const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2)); | 987 const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2)); |
| 1033 const String& name = String::Handle(ic_data.target_name()); | 988 const String& name = String::Handle(ic_data.target_name()); |
| 1034 const MegamorphicCache& cache = MegamorphicCache::Handle( | 989 const MegamorphicCache& cache = MegamorphicCache::Handle( |
| 1035 isolate->megamorphic_cache_table()->Lookup(name, descriptor)); | 990 isolate->megamorphic_cache_table()->Lookup(name, descriptor)); |
| 1036 Class& cls = Class::Handle(receiver.clazz()); | 991 Class& cls = Class::Handle(receiver.clazz()); |
| 1037 ASSERT(!cls.IsNull()); | 992 ASSERT(!cls.IsNull()); |
| 1038 if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) { | 993 if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) { |
| 1039 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", | 994 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1067 } | 1022 } |
| 1068 | 1023 |
| 1069 | 1024 |
| 1070 // Updates IC data for two arguments. Used by the equality operation when | 1025 // Updates IC data for two arguments. Used by the equality operation when |
| 1071 // the control flow bypasses regular inline cache (null arguments). | 1026 // the control flow bypasses regular inline cache (null arguments). |
| 1072 // Arg0: Receiver object. | 1027 // Arg0: Receiver object. |
| 1073 // Arg1: Argument after receiver. | 1028 // Arg1: Argument after receiver. |
| 1074 // Arg2: Target's name. | 1029 // Arg2: Target's name. |
| 1075 // Arg3: ICData. | 1030 // Arg3: ICData. |
| 1076 DEFINE_RUNTIME_ENTRY(UpdateICDataTwoArgs, 4) { | 1031 DEFINE_RUNTIME_ENTRY(UpdateICDataTwoArgs, 4) { |
| 1077 ASSERT(arguments.ArgCount() == | |
| 1078 kUpdateICDataTwoArgsRuntimeEntry.argument_count()); | |
| 1079 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 1032 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1080 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); | 1033 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 1081 const String& target_name = String::CheckedHandle(arguments.ArgAt(2)); | 1034 const String& target_name = String::CheckedHandle(arguments.ArgAt(2)); |
| 1082 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(3)); | 1035 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(3)); |
| 1083 GrowableArray<const Instance*> args(2); | 1036 GrowableArray<const Instance*> args(2); |
| 1084 args.Add(&receiver); | 1037 args.Add(&receiver); |
| 1085 args.Add(&arg1); | 1038 args.Add(&arg1); |
| 1086 const intptr_t kNumArguments = 2; | 1039 const intptr_t kNumArguments = 2; |
| 1087 ArgumentsDescriptor args_desc( | 1040 ArgumentsDescriptor args_desc( |
| 1088 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 1041 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); |
| 1089 const Function& target_function = Function::Handle( | 1042 const Function& target_function = Function::Handle( |
| 1090 Resolver::ResolveDynamic(receiver, | 1043 Resolver::ResolveDynamic(receiver, |
| 1091 target_name, | 1044 target_name, |
| 1092 args_desc)); | 1045 args_desc)); |
| 1093 ASSERT(!target_function.IsNull()); | 1046 ASSERT(!target_function.IsNull()); |
| 1094 GrowableArray<intptr_t> class_ids(kNumArguments); | 1047 GrowableArray<intptr_t> class_ids(kNumArguments); |
| 1095 ASSERT(ic_data.num_args_tested() == kNumArguments); | 1048 ASSERT(ic_data.num_args_tested() == kNumArguments); |
| 1096 class_ids.Add(receiver.GetClassId()); | 1049 class_ids.Add(receiver.GetClassId()); |
| 1097 class_ids.Add(arg1.GetClassId()); | 1050 class_ids.Add(arg1.GetClassId()); |
| 1098 ic_data.AddCheck(class_ids, target_function); | 1051 ic_data.AddCheck(class_ids, target_function); |
| 1099 } | 1052 } |
| 1100 | 1053 |
| 1101 | 1054 |
| 1102 // Invoke appropriate noSuchMethod function. | 1055 // Invoke appropriate noSuchMethod function. |
| 1103 // Arg0: receiver. | 1056 // Arg0: receiver. |
| 1104 // Arg1: ic-data. | 1057 // Arg1: ic-data. |
| 1105 // Arg2: arguments descriptor array. | 1058 // Arg2: arguments descriptor array. |
| 1106 // Arg3: arguments array. | 1059 // Arg3: arguments array. |
| 1107 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { | 1060 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { |
| 1108 ASSERT(arguments.ArgCount() == | |
| 1109 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count()); | |
| 1110 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 1061 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1111 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 1062 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 1112 const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(2)); | 1063 const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(2)); |
| 1113 const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3)); | 1064 const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3)); |
| 1114 | 1065 |
| 1115 String& original_function_name = String::Handle(ic_data.target_name()); | 1066 String& original_function_name = String::Handle(ic_data.target_name()); |
| 1116 if (receiver.IsClosure()) { | 1067 if (receiver.IsClosure()) { |
| 1117 // For closure the function name is always 'call'. Replace it with the | 1068 // For closure the function name is always 'call'. Replace it with the |
| 1118 // name of the closurized function so that exception contains more | 1069 // name of the closurized function so that exception contains more |
| 1119 // relevant information. | 1070 // relevant information. |
| 1120 const Function& function = Function::Handle(Closure::function(receiver)); | 1071 const Function& function = Function::Handle(Closure::function(receiver)); |
| 1121 original_function_name = function.QualifiedUserVisibleName(); | 1072 original_function_name = function.QualifiedUserVisibleName(); |
| 1122 } | 1073 } |
| 1123 const Object& result = Object::Handle( | 1074 const Object& result = Object::Handle( |
| 1124 DartEntry::InvokeNoSuchMethod(receiver, | 1075 DartEntry::InvokeNoSuchMethod(receiver, |
| 1125 original_function_name, | 1076 original_function_name, |
| 1126 orig_arguments, | 1077 orig_arguments, |
| 1127 orig_arguments_desc)); | 1078 orig_arguments_desc)); |
| 1128 CheckResultError(result); | 1079 CheckResultError(result); |
| 1129 arguments.SetReturn(result); | 1080 arguments.SetReturn(result); |
| 1130 } | 1081 } |
| 1131 | 1082 |
| 1132 | 1083 |
| 1133 // A non-closure object was invoked as a closure, so call the "call" method | 1084 // A non-closure object was invoked as a closure, so call the "call" method |
| 1134 // on it. | 1085 // on it. |
| 1135 // Arg0: arguments descriptor. | 1086 // Arg0: arguments descriptor. |
| 1136 // Arg1: arguments array, including non-closure object. | 1087 // Arg1: arguments array, including non-closure object. |
| 1137 DEFINE_RUNTIME_ENTRY(InvokeNonClosure, 2) { | 1088 DEFINE_RUNTIME_ENTRY(InvokeNonClosure, 2) { |
| 1138 ASSERT(arguments.ArgCount() == | |
| 1139 kInvokeNonClosureRuntimeEntry.argument_count()); | |
| 1140 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(0)); | 1089 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(0)); |
| 1141 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(1)); | 1090 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(1)); |
| 1142 | 1091 |
| 1143 const Object& result = Object::Handle( | 1092 const Object& result = Object::Handle( |
| 1144 DartEntry::InvokeClosure(function_args, args_descriptor)); | 1093 DartEntry::InvokeClosure(function_args, args_descriptor)); |
| 1145 CheckResultError(result); | 1094 CheckResultError(result); |
| 1146 arguments.SetReturn(result); | 1095 arguments.SetReturn(result); |
| 1147 } | 1096 } |
| 1148 | 1097 |
| 1149 | 1098 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1199 // 1. If the call was a getter o.f, there may be an instance function with | 1148 // 1. If the call was a getter o.f, there may be an instance function with |
| 1200 // the same name. If so, create an implicit closure and return it. | 1149 // the same name. If so, create an implicit closure and return it. |
| 1201 // | 1150 // |
| 1202 // 2. If the call was an instance call o.f(...), there may be a getter with | 1151 // 2. If the call was an instance call o.f(...), there may be a getter with |
| 1203 // the same name. If so, invoke it. If the value is a closure, invoke | 1152 // the same name. If so, invoke it. If the value is a closure, invoke |
| 1204 // it with the given arguments. If the value is a non-closure, attempt | 1153 // it with the given arguments. If the value is a non-closure, attempt |
| 1205 // to invoke "call" on it. | 1154 // to invoke "call" on it. |
| 1206 // | 1155 // |
| 1207 // 3. There is no such method. | 1156 // 3. There is no such method. |
| 1208 DEFINE_RUNTIME_ENTRY(InstanceFunctionLookup, 4) { | 1157 DEFINE_RUNTIME_ENTRY(InstanceFunctionLookup, 4) { |
| 1209 ASSERT(arguments.ArgCount() == | |
| 1210 kInstanceFunctionLookupRuntimeEntry.argument_count()); | |
| 1211 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 1158 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1212 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 1159 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 1213 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(2)); | 1160 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(2)); |
| 1214 const Array& args = Array::CheckedHandle(arguments.ArgAt(3)); | 1161 const Array& args = Array::CheckedHandle(arguments.ArgAt(3)); |
| 1215 | 1162 |
| 1216 const Class& receiver_class = Class::Handle(receiver.clazz()); | 1163 const Class& receiver_class = Class::Handle(receiver.clazz()); |
| 1217 const String& target_name = String::Handle(ic_data.target_name()); | 1164 const String& target_name = String::Handle(ic_data.target_name()); |
| 1218 | 1165 |
| 1219 Object& result = Object::Handle(); | 1166 Object& result = Object::Handle(); |
| 1220 if (!ResolveCallThroughGetter(receiver, | 1167 if (!ResolveCallThroughGetter(receiver, |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1304 } | 1251 } |
| 1305 // TODO(5442338): Abort as this should not happen. | 1252 // TODO(5442338): Abort as this should not happen. |
| 1306 function.set_usage_counter(kLowInvocationCount); | 1253 function.set_usage_counter(kLowInvocationCount); |
| 1307 return false; | 1254 return false; |
| 1308 } | 1255 } |
| 1309 return true; | 1256 return true; |
| 1310 } | 1257 } |
| 1311 | 1258 |
| 1312 | 1259 |
| 1313 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { | 1260 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { |
| 1314 ASSERT(arguments.ArgCount() == | |
| 1315 kStackOverflowRuntimeEntry.argument_count()); | |
| 1316 #if defined(USING_SIMULATOR) | 1261 #if defined(USING_SIMULATOR) |
| 1317 uword stack_pos = Simulator::Current()->get_register(SPREG); | 1262 uword stack_pos = Simulator::Current()->get_register(SPREG); |
| 1318 #else | 1263 #else |
| 1319 uword stack_pos = reinterpret_cast<uword>(&arguments); | 1264 uword stack_pos = reinterpret_cast<uword>(&arguments); |
| 1320 #endif | 1265 #endif |
| 1321 | 1266 |
| 1322 // If an interrupt happens at the same time as a stack overflow, we | 1267 // If an interrupt happens at the same time as a stack overflow, we |
| 1323 // process the stack overflow first. | 1268 // process the stack overflow first. |
| 1324 if (stack_pos < isolate->saved_stack_limit()) { | 1269 if (stack_pos < isolate->saved_stack_limit()) { |
| 1325 // Use the preallocated stack overflow exception to avoid calling | 1270 // Use the preallocated stack overflow exception to avoid calling |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1391 uword optimized_entry = | 1336 uword optimized_entry = |
| 1392 Instructions::Handle(optimized_code.instructions()).EntryPoint(); | 1337 Instructions::Handle(optimized_code.instructions()).EntryPoint(); |
| 1393 function.SetCode(original_code); | 1338 function.SetCode(original_code); |
| 1394 frame->set_pc(optimized_entry); | 1339 frame->set_pc(optimized_entry); |
| 1395 } | 1340 } |
| 1396 } | 1341 } |
| 1397 } | 1342 } |
| 1398 | 1343 |
| 1399 | 1344 |
| 1400 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { | 1345 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { |
| 1401 ASSERT(arguments.ArgCount() == | |
| 1402 kTraceICCallRuntimeEntry.argument_count()); | |
| 1403 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); | 1346 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); |
| 1404 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); | 1347 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); |
| 1405 DartFrameIterator iterator; | 1348 DartFrameIterator iterator; |
| 1406 StackFrame* frame = iterator.NextFrame(); | 1349 StackFrame* frame = iterator.NextFrame(); |
| 1407 ASSERT(frame != NULL); | 1350 ASSERT(frame != NULL); |
| 1408 OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd | 1351 OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd |
| 1409 " %s %s\n", | 1352 " %s %s\n", |
| 1410 frame->pc(), | 1353 frame->pc(), |
| 1411 ic_data.raw(), | 1354 ic_data.raw(), |
| 1412 function.usage_counter(), | 1355 function.usage_counter(), |
| 1413 ic_data.NumberOfChecks(), | 1356 ic_data.NumberOfChecks(), |
| 1414 ic_data.is_closure_call() ? "closure" : "", | 1357 ic_data.is_closure_call() ? "closure" : "", |
| 1415 function.ToFullyQualifiedCString()); | 1358 function.ToFullyQualifiedCString()); |
| 1416 } | 1359 } |
| 1417 | 1360 |
| 1418 | 1361 |
| 1419 // This is called from function that needs to be optimized. | 1362 // This is called from function that needs to be optimized. |
| 1420 // The requesting function can be already optimized (reoptimization). | 1363 // The requesting function can be already optimized (reoptimization). |
| 1421 // Returns the Code object where to continue execution. | 1364 // Returns the Code object where to continue execution. |
| 1422 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { | 1365 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { |
| 1423 ASSERT(arguments.ArgCount() == | |
| 1424 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); | |
| 1425 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 1366 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 1426 ASSERT(!function.IsNull()); | 1367 ASSERT(!function.IsNull()); |
| 1427 | 1368 |
| 1428 if (CanOptimizeFunction(function, isolate)) { | 1369 if (CanOptimizeFunction(function, isolate)) { |
| 1429 const Error& error = | 1370 const Error& error = |
| 1430 Error::Handle(Compiler::CompileOptimizedFunction(function)); | 1371 Error::Handle(Compiler::CompileOptimizedFunction(function)); |
| 1431 if (!error.IsNull()) { | 1372 if (!error.IsNull()) { |
| 1432 Exceptions::PropagateError(error); | 1373 Exceptions::PropagateError(error); |
| 1433 } | 1374 } |
| 1434 const Code& optimized_code = Code::Handle(function.CurrentCode()); | 1375 const Code& optimized_code = Code::Handle(function.CurrentCode()); |
| 1435 ASSERT(!optimized_code.IsNull()); | 1376 ASSERT(!optimized_code.IsNull()); |
| 1436 // Reset usage counter for reoptimization. | 1377 // Reset usage counter for reoptimization. |
| 1437 function.set_usage_counter(0); | 1378 function.set_usage_counter(0); |
| 1438 } | 1379 } |
| 1439 arguments.SetReturn(Code::Handle(function.CurrentCode())); | 1380 arguments.SetReturn(Code::Handle(function.CurrentCode())); |
| 1440 } | 1381 } |
| 1441 | 1382 |
| 1442 | 1383 |
| 1443 // The caller must be a static call in a Dart frame, or an entry frame. | 1384 // The caller must be a static call in a Dart frame, or an entry frame. |
| 1444 // Patch static call to point to valid code's entry point. | 1385 // Patch static call to point to valid code's entry point. |
| 1445 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { | 1386 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { |
| 1446 ASSERT(arguments.ArgCount() == | |
| 1447 kFixCallersTargetRuntimeEntry.argument_count()); | |
| 1448 | |
| 1449 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); | 1387 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); |
| 1450 StackFrame* frame = iterator.NextFrame(); | 1388 StackFrame* frame = iterator.NextFrame(); |
| 1451 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { | 1389 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { |
| 1452 frame = iterator.NextFrame(); | 1390 frame = iterator.NextFrame(); |
| 1453 } | 1391 } |
| 1454 ASSERT(frame != NULL); | 1392 ASSERT(frame != NULL); |
| 1455 if (frame->IsEntryFrame()) { | 1393 if (frame->IsEntryFrame()) { |
| 1456 // Since function's current code is always unpatched, the entry frame always | 1394 // Since function's current code is always unpatched, the entry frame always |
| 1457 // calls to unpatched code. | 1395 // calls to unpatched code. |
| 1458 UNREACHABLE(); | 1396 UNREACHABLE(); |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1877 UNIMPLEMENTED(); | 1815 UNIMPLEMENTED(); |
| 1878 return Field::kNoFixedLength; | 1816 return Field::kNoFixedLength; |
| 1879 } | 1817 } |
| 1880 | 1818 |
| 1881 | 1819 |
| 1882 // Update global type feedback recorded for a field recording the assignment | 1820 // Update global type feedback recorded for a field recording the assignment |
| 1883 // of the given value. | 1821 // of the given value. |
| 1884 // Arg0: Field object; | 1822 // Arg0: Field object; |
| 1885 // Arg1: Value that is being stored. | 1823 // Arg1: Value that is being stored. |
| 1886 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1824 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
| 1887 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); | |
| 1888 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1825 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
| 1889 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1826 const Object& value = Object::Handle(arguments.ArgAt(1)); |
| 1890 const intptr_t cid = value.GetClassId(); | 1827 const intptr_t cid = value.GetClassId(); |
| 1891 field.UpdateCid(cid); | 1828 field.UpdateCid(cid); |
| 1892 intptr_t list_length = Field::kNoFixedLength; | 1829 intptr_t list_length = Field::kNoFixedLength; |
| 1893 if ((field.guarded_cid() != kDynamicCid) && | 1830 if ((field.guarded_cid() != kDynamicCid) && |
| 1894 field.is_final() && RawObject::IsBuiltinListClassId(cid)) { | 1831 field.is_final() && RawObject::IsBuiltinListClassId(cid)) { |
| 1895 list_length = GetListLength(value); | 1832 list_length = GetListLength(value); |
| 1896 } | 1833 } |
| 1897 field.UpdateLength(list_length); | 1834 field.UpdateLength(list_length); |
| 1898 } | 1835 } |
| 1899 | 1836 |
| 1900 } // namespace dart | 1837 } // namespace dart |
| OLD | NEW |