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 |