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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/runtime_entry.h ('k') | runtime/vm/runtime_entry_arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/runtime_entry.h" 5 #include "vm/runtime_entry.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/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
11 #include "vm/dart_api_impl.h" 11 #include "vm/dart_api_impl.h"
12 #include "vm/dart_entry.h" 12 #include "vm/dart_entry.h"
13 #include "vm/debugger.h" 13 #include "vm/debugger.h"
14 #include "vm/deopt_instructions.h" 14 #include "vm/deopt_instructions.h"
15 #include "vm/exceptions.h" 15 #include "vm/exceptions.h"
16 #include "vm/flags.h" 16 #include "vm/flags.h"
17 #include "vm/object_store.h"
18 #include "vm/message.h" 17 #include "vm/message.h"
19 #include "vm/message_handler.h" 18 #include "vm/message_handler.h"
19 #include "vm/object_store.h"
20 #include "vm/parser.h" 20 #include "vm/parser.h"
21 #include "vm/resolver.h" 21 #include "vm/resolver.h"
22 #include "vm/service_isolate.h" 22 #include "vm/service_isolate.h"
23 #include "vm/stack_frame.h" 23 #include "vm/stack_frame.h"
24 #include "vm/symbols.h" 24 #include "vm/symbols.h"
25 #include "vm/thread_registry.h" 25 #include "vm/thread_registry.h"
26 #include "vm/verifier.h" 26 #include "vm/verifier.h"
27 27
28 namespace dart { 28 namespace dart {
29 29
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 DECLARE_FLAG(bool, reload_every_back_off); 85 DECLARE_FLAG(bool, reload_every_back_off);
86 86
87 #ifdef DEBUG 87 #ifdef DEBUG
88 DEFINE_FLAG(charp, 88 DEFINE_FLAG(charp,
89 gc_at_instance_allocation, 89 gc_at_instance_allocation,
90 NULL, 90 NULL,
91 "Perform a GC before allocation of instances of " 91 "Perform a GC before allocation of instances of "
92 "the specified class"); 92 "the specified class");
93 #endif 93 #endif
94 94
95
96 #if defined(TESTING) || defined(DEBUG) 95 #if defined(TESTING) || defined(DEBUG)
97 void VerifyOnTransition() { 96 void VerifyOnTransition() {
98 Thread* thread = Thread::Current(); 97 Thread* thread = Thread::Current();
99 TransitionGeneratedToVM transition(thread); 98 TransitionGeneratedToVM transition(thread);
100 thread->isolate()->heap()->WaitForSweeperTasks(thread); 99 thread->isolate()->heap()->WaitForSweeperTasks(thread);
101 SafepointOperationScope safepoint_scope(thread); 100 SafepointOperationScope safepoint_scope(thread);
102 VerifyPointersVisitor::VerifyPointers(); 101 VerifyPointersVisitor::VerifyPointers();
103 thread->isolate()->heap()->Verify(); 102 thread->isolate()->heap()->Verify();
104 } 103 }
105 #endif 104 #endif
106 105
107
108 // Add function to a class and that class to the class dictionary so that 106 // Add function to a class and that class to the class dictionary so that
109 // frame walking can be used. 107 // frame walking can be used.
110 const Function& RegisterFakeFunction(const char* name, const Code& code) { 108 const Function& RegisterFakeFunction(const char* name, const Code& code) {
111 Thread* thread = Thread::Current(); 109 Thread* thread = Thread::Current();
112 const String& class_name = String::Handle(Symbols::New(thread, "ownerClass")); 110 const String& class_name = String::Handle(Symbols::New(thread, "ownerClass"));
113 const Script& script = Script::Handle(); 111 const Script& script = Script::Handle();
114 const Library& lib = Library::Handle(Library::CoreLibrary()); 112 const Library& lib = Library::Handle(Library::CoreLibrary());
115 const Class& owner_class = Class::Handle( 113 const Class& owner_class = Class::Handle(
116 Class::New(lib, class_name, script, TokenPosition::kNoSource)); 114 Class::New(lib, class_name, script, TokenPosition::kNoSource));
117 const String& function_name = String::ZoneHandle(Symbols::New(thread, name)); 115 const String& function_name = String::ZoneHandle(Symbols::New(thread, name));
118 const Function& function = Function::ZoneHandle(Function::New( 116 const Function& function = Function::ZoneHandle(Function::New(
119 function_name, RawFunction::kRegularFunction, true, false, false, false, 117 function_name, RawFunction::kRegularFunction, true, false, false, false,
120 false, owner_class, TokenPosition::kMinSource)); 118 false, owner_class, TokenPosition::kMinSource));
121 const Array& functions = Array::Handle(Array::New(1)); 119 const Array& functions = Array::Handle(Array::New(1));
122 functions.SetAt(0, function); 120 functions.SetAt(0, function);
123 owner_class.SetFunctions(functions); 121 owner_class.SetFunctions(functions);
124 lib.AddClass(owner_class); 122 lib.AddClass(owner_class);
125 function.AttachCode(code); 123 function.AttachCode(code);
126 return function; 124 return function;
127 } 125 }
128 126
129
130 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { 127 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) {
131 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); 128 const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
132 const String& function_name = String::Handle(function.name()); 129 const String& function_name = String::Handle(function.name());
133 const String& class_name = 130 const String& class_name =
134 String::Handle(Class::Handle(function.Owner()).Name()); 131 String::Handle(Class::Handle(function.Owner()).Name());
135 OS::PrintErr("> Entering '%s.%s'\n", class_name.ToCString(), 132 OS::PrintErr("> Entering '%s.%s'\n", class_name.ToCString(),
136 function_name.ToCString()); 133 function_name.ToCString());
137 } 134 }
138 135
139
140 DEFINE_RUNTIME_ENTRY(TraceFunctionExit, 1) { 136 DEFINE_RUNTIME_ENTRY(TraceFunctionExit, 1) {
141 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); 137 const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
142 const String& function_name = String::Handle(function.name()); 138 const String& function_name = String::Handle(function.name());
143 const String& class_name = 139 const String& class_name =
144 String::Handle(Class::Handle(function.Owner()).Name()); 140 String::Handle(Class::Handle(function.Owner()).Name());
145 OS::PrintErr("< Exiting '%s.%s'\n", class_name.ToCString(), 141 OS::PrintErr("< Exiting '%s.%s'\n", class_name.ToCString(),
146 function_name.ToCString()); 142 function_name.ToCString());
147 } 143 }
148 144
149
150 DEFINE_RUNTIME_ENTRY(RangeError, 2) { 145 DEFINE_RUNTIME_ENTRY(RangeError, 2) {
151 const Instance& length = Instance::CheckedHandle(arguments.ArgAt(0)); 146 const Instance& length = Instance::CheckedHandle(arguments.ArgAt(0));
152 const Instance& index = Instance::CheckedHandle(arguments.ArgAt(1)); 147 const Instance& index = Instance::CheckedHandle(arguments.ArgAt(1));
153 if (!length.IsInteger()) { 148 if (!length.IsInteger()) {
154 // Throw: new ArgumentError.value(length, "length", "is not an integer"); 149 // Throw: new ArgumentError.value(length, "length", "is not an integer");
155 const Array& args = Array::Handle(Array::New(3)); 150 const Array& args = Array::Handle(Array::New(3));
156 args.SetAt(0, length); 151 args.SetAt(0, length);
157 args.SetAt(1, Symbols::Length()); 152 args.SetAt(1, Symbols::Length());
158 args.SetAt(2, String::Handle(String::New("is not an integer"))); 153 args.SetAt(2, String::Handle(String::New("is not an integer")));
159 Exceptions::ThrowByType(Exceptions::kArgumentValue, args); 154 Exceptions::ThrowByType(Exceptions::kArgumentValue, args);
160 } 155 }
161 if (!index.IsInteger()) { 156 if (!index.IsInteger()) {
162 // Throw: new ArgumentError.value(index, "index", "is not an integer"); 157 // Throw: new ArgumentError.value(index, "index", "is not an integer");
163 const Array& args = Array::Handle(Array::New(3)); 158 const Array& args = Array::Handle(Array::New(3));
164 args.SetAt(0, index); 159 args.SetAt(0, index);
165 args.SetAt(1, Symbols::Index()); 160 args.SetAt(1, Symbols::Index());
166 args.SetAt(2, String::Handle(String::New("is not an integer"))); 161 args.SetAt(2, String::Handle(String::New("is not an integer")));
167 Exceptions::ThrowByType(Exceptions::kArgumentValue, args); 162 Exceptions::ThrowByType(Exceptions::kArgumentValue, args);
168 } 163 }
169 // Throw: new RangeError.range(index, 0, length, "length"); 164 // Throw: new RangeError.range(index, 0, length, "length");
170 const Array& args = Array::Handle(Array::New(4)); 165 const Array& args = Array::Handle(Array::New(4));
171 args.SetAt(0, index); 166 args.SetAt(0, index);
172 args.SetAt(1, Integer::Handle(Integer::New(0))); 167 args.SetAt(1, Integer::Handle(Integer::New(0)));
173 args.SetAt(2, length); 168 args.SetAt(2, length);
174 args.SetAt(3, Symbols::Length()); 169 args.SetAt(3, Symbols::Length());
175 Exceptions::ThrowByType(Exceptions::kRange, args); 170 Exceptions::ThrowByType(Exceptions::kRange, args);
176 } 171 }
177 172
178
179 // Allocation of a fixed length array of given element type. 173 // Allocation of a fixed length array of given element type.
180 // This runtime entry is never called for allocating a List of a generic type, 174 // This runtime entry is never called for allocating a List of a generic type,
181 // because a prior run time call instantiates the element type if necessary. 175 // because a prior run time call instantiates the element type if necessary.
182 // Arg0: array length. 176 // Arg0: array length.
183 // Arg1: array type arguments, i.e. vector of 1 type, the element type. 177 // Arg1: array type arguments, i.e. vector of 1 type, the element type.
184 // Return value: newly allocated array of length arg0. 178 // Return value: newly allocated array of length arg0.
185 DEFINE_RUNTIME_ENTRY(AllocateArray, 2) { 179 DEFINE_RUNTIME_ENTRY(AllocateArray, 2) {
186 const Instance& length = Instance::CheckedHandle(arguments.ArgAt(0)); 180 const Instance& length = Instance::CheckedHandle(arguments.ArgAt(0));
187 if (!length.IsInteger()) { 181 if (!length.IsInteger()) {
188 // Throw: new ArgumentError.value(length, "length", "is not an integer"); 182 // Throw: new ArgumentError.value(length, "length", "is not an integer");
(...skipping 21 matching lines...) Expand all
210 } 204 }
211 // Throw: new RangeError.range(length, 0, Array::kMaxElements, "length"); 205 // Throw: new RangeError.range(length, 0, Array::kMaxElements, "length");
212 const Array& args = Array::Handle(Array::New(4)); 206 const Array& args = Array::Handle(Array::New(4));
213 args.SetAt(0, length); 207 args.SetAt(0, length);
214 args.SetAt(1, Integer::Handle(Integer::New(0))); 208 args.SetAt(1, Integer::Handle(Integer::New(0)));
215 args.SetAt(2, Integer::Handle(Integer::New(Array::kMaxElements))); 209 args.SetAt(2, Integer::Handle(Integer::New(Array::kMaxElements)));
216 args.SetAt(3, Symbols::Length()); 210 args.SetAt(3, Symbols::Length());
217 Exceptions::ThrowByType(Exceptions::kRange, args); 211 Exceptions::ThrowByType(Exceptions::kRange, args);
218 } 212 }
219 213
220
221 // Helper returning the token position of the Dart caller. 214 // Helper returning the token position of the Dart caller.
222 static TokenPosition GetCallerLocation() { 215 static TokenPosition GetCallerLocation() {
223 DartFrameIterator iterator(Thread::Current(), 216 DartFrameIterator iterator(Thread::Current(),
224 StackFrameIterator::kNoCrossThreadIteration); 217 StackFrameIterator::kNoCrossThreadIteration);
225 StackFrame* caller_frame = iterator.NextFrame(); 218 StackFrame* caller_frame = iterator.NextFrame();
226 ASSERT(caller_frame != NULL); 219 ASSERT(caller_frame != NULL);
227 return caller_frame->GetTokenPos(); 220 return caller_frame->GetTokenPos();
228 } 221 }
229 222
230
231 // Allocate a new object. 223 // Allocate a new object.
232 // Arg0: class of the object that needs to be allocated. 224 // Arg0: class of the object that needs to be allocated.
233 // Arg1: type arguments of the object that needs to be allocated. 225 // Arg1: type arguments of the object that needs to be allocated.
234 // Return value: newly allocated object. 226 // Return value: newly allocated object.
235 DEFINE_RUNTIME_ENTRY(AllocateObject, 2) { 227 DEFINE_RUNTIME_ENTRY(AllocateObject, 2) {
236 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); 228 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0));
237 229
238 #ifdef DEBUG 230 #ifdef DEBUG
239 if (FLAG_gc_at_instance_allocation != NULL) { 231 if (FLAG_gc_at_instance_allocation != NULL) {
240 const String& name = String::Handle(cls.Name()); 232 const String& name = String::Handle(cls.Name());
(...skipping 17 matching lines...) Expand all
258 TypeArguments::CheckedHandle(arguments.ArgAt(1)); 250 TypeArguments::CheckedHandle(arguments.ArgAt(1));
259 // Unless null (for a raw type), the type argument vector may be longer than 251 // Unless null (for a raw type), the type argument vector may be longer than
260 // necessary due to a type optimization reusing the type argument vector of 252 // necessary due to a type optimization reusing the type argument vector of
261 // the instantiator. 253 // the instantiator.
262 ASSERT(type_arguments.IsNull() || 254 ASSERT(type_arguments.IsNull() ||
263 (type_arguments.IsInstantiated() && 255 (type_arguments.IsInstantiated() &&
264 (type_arguments.Length() >= cls.NumTypeArguments()))); 256 (type_arguments.Length() >= cls.NumTypeArguments())));
265 instance.SetTypeArguments(type_arguments); 257 instance.SetTypeArguments(type_arguments);
266 } 258 }
267 259
268
269 // Instantiate type. 260 // Instantiate type.
270 // Arg0: uninstantiated type. 261 // Arg0: uninstantiated type.
271 // Arg1: instantiator type arguments. 262 // Arg1: instantiator type arguments.
272 // Arg2: function type arguments. 263 // Arg2: function type arguments.
273 // Return value: instantiated type. 264 // Return value: instantiated type.
274 DEFINE_RUNTIME_ENTRY(InstantiateType, 3) { 265 DEFINE_RUNTIME_ENTRY(InstantiateType, 3) {
275 AbstractType& type = AbstractType::CheckedHandle(zone, arguments.ArgAt(0)); 266 AbstractType& type = AbstractType::CheckedHandle(zone, arguments.ArgAt(0));
276 const TypeArguments& instantiator_type_arguments = 267 const TypeArguments& instantiator_type_arguments =
277 TypeArguments::CheckedHandle(zone, arguments.ArgAt(1)); 268 TypeArguments::CheckedHandle(zone, arguments.ArgAt(1));
278 const TypeArguments& function_type_arguments = 269 const TypeArguments& function_type_arguments =
(...skipping 19 matching lines...) Expand all
298 } 289 }
299 if (type.IsTypeRef()) { 290 if (type.IsTypeRef()) {
300 type = TypeRef::Cast(type).type(); 291 type = TypeRef::Cast(type).type();
301 ASSERT(!type.IsTypeRef()); 292 ASSERT(!type.IsTypeRef());
302 ASSERT(type.IsCanonical()); 293 ASSERT(type.IsCanonical());
303 } 294 }
304 ASSERT(!type.IsNull() && type.IsInstantiated()); 295 ASSERT(!type.IsNull() && type.IsInstantiated());
305 arguments.SetReturn(type); 296 arguments.SetReturn(type);
306 } 297 }
307 298
308
309 // Instantiate type arguments. 299 // Instantiate type arguments.
310 // Arg0: uninstantiated type arguments. 300 // Arg0: uninstantiated type arguments.
311 // Arg1: instantiator type arguments. 301 // Arg1: instantiator type arguments.
312 // Arg2: function type arguments. 302 // Arg2: function type arguments.
313 // Return value: instantiated type arguments. 303 // Return value: instantiated type arguments.
314 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 3) { 304 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 3) {
315 TypeArguments& type_arguments = 305 TypeArguments& type_arguments =
316 TypeArguments::CheckedHandle(zone, arguments.ArgAt(0)); 306 TypeArguments::CheckedHandle(zone, arguments.ArgAt(0));
317 const TypeArguments& instantiator_type_arguments = 307 const TypeArguments& instantiator_type_arguments =
318 TypeArguments::CheckedHandle(zone, arguments.ArgAt(1)); 308 TypeArguments::CheckedHandle(zone, arguments.ArgAt(1));
(...skipping 22 matching lines...) Expand all
341 UNREACHABLE(); 331 UNREACHABLE();
342 } 332 }
343 } else { 333 } else {
344 type_arguments = type_arguments.InstantiateAndCanonicalizeFrom( 334 type_arguments = type_arguments.InstantiateAndCanonicalizeFrom(
345 instantiator_type_arguments, function_type_arguments, NULL); 335 instantiator_type_arguments, function_type_arguments, NULL);
346 } 336 }
347 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); 337 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated());
348 arguments.SetReturn(type_arguments); 338 arguments.SetReturn(type_arguments);
349 } 339 }
350 340
351
352 // Allocate a new context large enough to hold the given number of variables. 341 // Allocate a new context large enough to hold the given number of variables.
353 // Arg0: number of variables. 342 // Arg0: number of variables.
354 // Return value: newly allocated context. 343 // Return value: newly allocated context.
355 DEFINE_RUNTIME_ENTRY(AllocateContext, 1) { 344 DEFINE_RUNTIME_ENTRY(AllocateContext, 1) {
356 const Smi& num_variables = Smi::CheckedHandle(zone, arguments.ArgAt(0)); 345 const Smi& num_variables = Smi::CheckedHandle(zone, arguments.ArgAt(0));
357 arguments.SetReturn(Context::Handle(Context::New(num_variables.Value()))); 346 arguments.SetReturn(Context::Handle(Context::New(num_variables.Value())));
358 } 347 }
359 348
360
361 // Make a copy of the given context, including the values of the captured 349 // Make a copy of the given context, including the values of the captured
362 // variables. 350 // variables.
363 // Arg0: the context to be cloned. 351 // Arg0: the context to be cloned.
364 // Return value: newly allocated context. 352 // Return value: newly allocated context.
365 DEFINE_RUNTIME_ENTRY(CloneContext, 1) { 353 DEFINE_RUNTIME_ENTRY(CloneContext, 1) {
366 const Context& ctx = Context::CheckedHandle(zone, arguments.ArgAt(0)); 354 const Context& ctx = Context::CheckedHandle(zone, arguments.ArgAt(0));
367 Context& cloned_ctx = 355 Context& cloned_ctx =
368 Context::Handle(zone, Context::New(ctx.num_variables())); 356 Context::Handle(zone, Context::New(ctx.num_variables()));
369 cloned_ctx.set_parent(Context::Handle(ctx.parent())); 357 cloned_ctx.set_parent(Context::Handle(ctx.parent()));
370 Object& inst = Object::Handle(zone); 358 Object& inst = Object::Handle(zone);
371 for (int i = 0; i < ctx.num_variables(); i++) { 359 for (int i = 0; i < ctx.num_variables(); i++) {
372 inst = ctx.At(i); 360 inst = ctx.At(i);
373 cloned_ctx.SetAt(i, inst); 361 cloned_ctx.SetAt(i, inst);
374 } 362 }
375 arguments.SetReturn(cloned_ctx); 363 arguments.SetReturn(cloned_ctx);
376 } 364 }
377 365
378
379 // Helper routine for tracing a type check. 366 // Helper routine for tracing a type check.
380 static void PrintTypeCheck(const char* message, 367 static void PrintTypeCheck(const char* message,
381 const Instance& instance, 368 const Instance& instance,
382 const AbstractType& type, 369 const AbstractType& type,
383 const TypeArguments& instantiator_type_arguments, 370 const TypeArguments& instantiator_type_arguments,
384 const TypeArguments& function_type_arguments, 371 const TypeArguments& function_type_arguments,
385 const Bool& result) { 372 const Bool& result) {
386 DartFrameIterator iterator(Thread::Current(), 373 DartFrameIterator iterator(Thread::Current(),
387 StackFrameIterator::kNoCrossThreadIteration); 374 StackFrameIterator::kNoCrossThreadIteration);
388 StackFrame* caller_frame = iterator.NextFrame(); 375 StackFrame* caller_frame = iterator.NextFrame();
(...skipping 24 matching lines...) Expand all
413 String::Handle(type.Name()).ToCString(), caller_frame->pc()); 400 String::Handle(type.Name()).ToCString(), caller_frame->pc());
414 if (!bound_error.IsNull()) { 401 if (!bound_error.IsNull()) {
415 OS::Print(" bound error: %s\n", bound_error.ToErrorCString()); 402 OS::Print(" bound error: %s\n", bound_error.ToErrorCString());
416 } 403 }
417 } 404 }
418 const Function& function = 405 const Function& function =
419 Function::Handle(caller_frame->LookupDartFunction()); 406 Function::Handle(caller_frame->LookupDartFunction());
420 OS::PrintErr(" -> Function %s\n", function.ToFullyQualifiedCString()); 407 OS::PrintErr(" -> Function %s\n", function.ToFullyQualifiedCString());
421 } 408 }
422 409
423
424 // This updates the type test cache, an array containing 5-value elements 410 // This updates the type test cache, an array containing 5-value elements
425 // (instance class (or function if the instance is a closure), instance type 411 // (instance class (or function if the instance is a closure), instance type
426 // arguments, instantiator type arguments, function type arguments, 412 // arguments, instantiator type arguments, function type arguments,
427 // and test_result). It can be applied to classes with type arguments in which 413 // and test_result). It can be applied to classes with type arguments in which
428 // case it contains just the result of the class subtype test, not including the 414 // case it contains just the result of the class subtype test, not including the
429 // evaluation of type arguments. 415 // evaluation of type arguments.
430 // This operation is currently very slow (lookup of code is not efficient yet). 416 // This operation is currently very slow (lookup of code is not efficient yet).
431 static void UpdateTypeTestCache( 417 static void UpdateTypeTestCache(
432 const Instance& instance, 418 const Instance& instance,
433 const AbstractType& type, 419 const AbstractType& type,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 test_type.type_class(), 549 test_type.type_class(),
564 String::Handle(Class::Handle(test_type.type_class()).Name()) 550 String::Handle(Class::Handle(test_type.type_class()).Name())
565 .ToCString(), 551 .ToCString(),
566 Class::Handle(test_type.type_class()).id(), 552 Class::Handle(test_type.type_class()).id(),
567 instantiator_type_arguments.raw(), 553 instantiator_type_arguments.raw(),
568 instantiator_type_arguments.ToCString(), function_type_arguments.raw(), 554 instantiator_type_arguments.ToCString(), function_type_arguments.raw(),
569 function_type_arguments.ToCString()); 555 function_type_arguments.ToCString());
570 } 556 }
571 } 557 }
572 558
573
574 // Check that the given instance is an instance of the given type. 559 // Check that the given instance is an instance of the given type.
575 // Tested instance may not be null, because the null test is inlined. 560 // Tested instance may not be null, because the null test is inlined.
576 // Arg0: instance being checked. 561 // Arg0: instance being checked.
577 // Arg1: type. 562 // Arg1: type.
578 // Arg2: type arguments of the instantiator of the type. 563 // Arg2: type arguments of the instantiator of the type.
579 // Arg3: type arguments of the function of the type. 564 // Arg3: type arguments of the function of the type.
580 // Arg4: SubtypeTestCache. 565 // Arg4: SubtypeTestCache.
581 // Return value: true or false, or may throw a type error in checked mode. 566 // Return value: true or false, or may throw a type error in checked mode.
582 DEFINE_RUNTIME_ENTRY(Instanceof, 5) { 567 DEFINE_RUNTIME_ENTRY(Instanceof, 5) {
583 const Instance& instance = Instance::CheckedHandle(zone, arguments.ArgAt(0)); 568 const Instance& instance = Instance::CheckedHandle(zone, arguments.ArgAt(0));
(...skipping 25 matching lines...) Expand all
609 Exceptions::CreateAndThrowTypeError(location, AbstractType::Handle(zone), 594 Exceptions::CreateAndThrowTypeError(location, AbstractType::Handle(zone),
610 AbstractType::Handle(zone), 595 AbstractType::Handle(zone),
611 Symbols::Empty(), bound_error_message); 596 Symbols::Empty(), bound_error_message);
612 UNREACHABLE(); 597 UNREACHABLE();
613 } 598 }
614 UpdateTypeTestCache(instance, type, instantiator_type_arguments, 599 UpdateTypeTestCache(instance, type, instantiator_type_arguments,
615 function_type_arguments, result, cache); 600 function_type_arguments, result, cache);
616 arguments.SetReturn(result); 601 arguments.SetReturn(result);
617 } 602 }
618 603
619
620 // Check that the type of the given instance is a subtype of the given type and 604 // Check that the type of the given instance is a subtype of the given type and
621 // can therefore be assigned. 605 // can therefore be assigned.
622 // Arg0: instance being assigned. 606 // Arg0: instance being assigned.
623 // Arg1: type being assigned to. 607 // Arg1: type being assigned to.
624 // Arg2: type arguments of the instantiator of the type being assigned to. 608 // Arg2: type arguments of the instantiator of the type being assigned to.
625 // Arg3: type arguments of the function of the type being assigned to. 609 // Arg3: type arguments of the function of the type being assigned to.
626 // Arg4: name of variable being assigned to. 610 // Arg4: name of variable being assigned to.
627 // Arg5: SubtypeTestCache. 611 // Arg5: SubtypeTestCache.
628 // Return value: instance if a subtype, otherwise throw a TypeError. 612 // Return value: instance if a subtype, otherwise throw a TypeError.
629 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) { 613 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 } 656 }
673 Exceptions::CreateAndThrowTypeError(location, src_type, dst_type, dst_name, 657 Exceptions::CreateAndThrowTypeError(location, src_type, dst_type, dst_name,
674 bound_error_message); 658 bound_error_message);
675 UNREACHABLE(); 659 UNREACHABLE();
676 } 660 }
677 UpdateTypeTestCache(src_instance, dst_type, instantiator_type_arguments, 661 UpdateTypeTestCache(src_instance, dst_type, instantiator_type_arguments,
678 function_type_arguments, Bool::True(), cache); 662 function_type_arguments, Bool::True(), cache);
679 arguments.SetReturn(src_instance); 663 arguments.SetReturn(src_instance);
680 } 664 }
681 665
682
683 // Report that the type of the given object is not bool in conditional context. 666 // Report that the type of the given object is not bool in conditional context.
684 // Throw assertion error if the object is null. (cf. Boolean Conversion 667 // Throw assertion error if the object is null. (cf. Boolean Conversion
685 // in language Spec.) 668 // in language Spec.)
686 // Arg0: bad object. 669 // Arg0: bad object.
687 // Return value: none, throws TypeError or AssertionError. 670 // Return value: none, throws TypeError or AssertionError.
688 DEFINE_RUNTIME_ENTRY(NonBoolTypeError, 1) { 671 DEFINE_RUNTIME_ENTRY(NonBoolTypeError, 1) {
689 const TokenPosition location = GetCallerLocation(); 672 const TokenPosition location = GetCallerLocation();
690 const Instance& src_instance = 673 const Instance& src_instance =
691 Instance::CheckedHandle(zone, arguments.ArgAt(0)); 674 Instance::CheckedHandle(zone, arguments.ArgAt(0));
692 675
(...skipping 19 matching lines...) Expand all
712 const Type& bool_interface = Type::Handle(Type::BoolType()); 695 const Type& bool_interface = Type::Handle(Type::BoolType());
713 const AbstractType& src_type = 696 const AbstractType& src_type =
714 AbstractType::Handle(zone, src_instance.GetType(Heap::kNew)); 697 AbstractType::Handle(zone, src_instance.GetType(Heap::kNew));
715 const String& no_bound_error = String::Handle(zone); 698 const String& no_bound_error = String::Handle(zone);
716 Exceptions::CreateAndThrowTypeError(location, src_type, bool_interface, 699 Exceptions::CreateAndThrowTypeError(location, src_type, bool_interface,
717 Symbols::BooleanExpression(), 700 Symbols::BooleanExpression(),
718 no_bound_error); 701 no_bound_error);
719 UNREACHABLE(); 702 UNREACHABLE();
720 } 703 }
721 704
722
723 // Report that the type of the type check is malformed or malbounded. 705 // Report that the type of the type check is malformed or malbounded.
724 // Arg0: src value. 706 // Arg0: src value.
725 // Arg1: name of destination being assigned to. 707 // Arg1: name of destination being assigned to.
726 // Arg2: type of destination being assigned to. 708 // Arg2: type of destination being assigned to.
727 // Return value: none, throws an exception. 709 // Return value: none, throws an exception.
728 DEFINE_RUNTIME_ENTRY(BadTypeError, 3) { 710 DEFINE_RUNTIME_ENTRY(BadTypeError, 3) {
729 const TokenPosition location = GetCallerLocation(); 711 const TokenPosition location = GetCallerLocation();
730 const Instance& src_value = Instance::CheckedHandle(zone, arguments.ArgAt(0)); 712 const Instance& src_value = Instance::CheckedHandle(zone, arguments.ArgAt(0));
731 const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(1)); 713 const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(1));
732 const AbstractType& dst_type = 714 const AbstractType& dst_type =
733 AbstractType::CheckedHandle(zone, arguments.ArgAt(2)); 715 AbstractType::CheckedHandle(zone, arguments.ArgAt(2));
734 const AbstractType& src_type = 716 const AbstractType& src_type =
735 AbstractType::Handle(zone, src_value.GetType(Heap::kNew)); 717 AbstractType::Handle(zone, src_value.GetType(Heap::kNew));
736 Exceptions::CreateAndThrowTypeError(location, src_type, dst_type, dst_name, 718 Exceptions::CreateAndThrowTypeError(location, src_type, dst_type, dst_name,
737 String::Handle(zone)); 719 String::Handle(zone));
738 UNREACHABLE(); 720 UNREACHABLE();
739 } 721 }
740 722
741
742 DEFINE_RUNTIME_ENTRY(Throw, 1) { 723 DEFINE_RUNTIME_ENTRY(Throw, 1) {
743 const Instance& exception = Instance::CheckedHandle(zone, arguments.ArgAt(0)); 724 const Instance& exception = Instance::CheckedHandle(zone, arguments.ArgAt(0));
744 Exceptions::Throw(thread, exception); 725 Exceptions::Throw(thread, exception);
745 } 726 }
746 727
747
748 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { 728 DEFINE_RUNTIME_ENTRY(ReThrow, 2) {
749 const Instance& exception = Instance::CheckedHandle(zone, arguments.ArgAt(0)); 729 const Instance& exception = Instance::CheckedHandle(zone, arguments.ArgAt(0));
750 const Instance& stacktrace = 730 const Instance& stacktrace =
751 Instance::CheckedHandle(zone, arguments.ArgAt(1)); 731 Instance::CheckedHandle(zone, arguments.ArgAt(1));
752 Exceptions::ReThrow(thread, exception, stacktrace); 732 Exceptions::ReThrow(thread, exception, stacktrace);
753 } 733 }
754 734
755
756 // Patches static call in optimized code with the target's entry point. 735 // Patches static call in optimized code with the target's entry point.
757 // Compiles target if necessary. 736 // Compiles target if necessary.
758 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { 737 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) {
759 DartFrameIterator iterator(thread, 738 DartFrameIterator iterator(thread,
760 StackFrameIterator::kNoCrossThreadIteration); 739 StackFrameIterator::kNoCrossThreadIteration);
761 StackFrame* caller_frame = iterator.NextFrame(); 740 StackFrame* caller_frame = iterator.NextFrame();
762 ASSERT(caller_frame != NULL); 741 ASSERT(caller_frame != NULL);
763 const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode()); 742 const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
764 ASSERT(!caller_code.IsNull()); 743 ASSERT(!caller_code.IsNull());
765 ASSERT(caller_code.is_optimized()); 744 ASSERT(caller_code.is_optimized());
(...skipping 10 matching lines...) Expand all
776 THR_Print("PatchStaticCall: patching caller pc %#" Px 755 THR_Print("PatchStaticCall: patching caller pc %#" Px
777 "" 756 ""
778 " to '%s' new entry point %#" Px " (%s)\n", 757 " to '%s' new entry point %#" Px " (%s)\n",
779 caller_frame->pc(), target_function.ToFullyQualifiedCString(), 758 caller_frame->pc(), target_function.ToFullyQualifiedCString(),
780 target_code.UncheckedEntryPoint(), 759 target_code.UncheckedEntryPoint(),
781 target_code.is_optimized() ? "optimized" : "unoptimized"); 760 target_code.is_optimized() ? "optimized" : "unoptimized");
782 } 761 }
783 arguments.SetReturn(target_code); 762 arguments.SetReturn(target_code);
784 } 763 }
785 764
786
787 // Result of an invoke may be an unhandled exception, in which case we 765 // Result of an invoke may be an unhandled exception, in which case we
788 // rethrow it. 766 // rethrow it.
789 static void CheckResultError(const Object& result) { 767 static void CheckResultError(const Object& result) {
790 if (result.IsError()) { 768 if (result.IsError()) {
791 Exceptions::PropagateError(Error::Cast(result)); 769 Exceptions::PropagateError(Error::Cast(result));
792 } 770 }
793 } 771 }
794 772
795
796 #if !defined(TARGET_ARCH_DBC) 773 #if !defined(TARGET_ARCH_DBC)
797 // Gets called from debug stub when code reaches a breakpoint 774 // Gets called from debug stub when code reaches a breakpoint
798 // set on a runtime stub call. 775 // set on a runtime stub call.
799 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { 776 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) {
800 if (!FLAG_support_debugger) { 777 if (!FLAG_support_debugger) {
801 UNREACHABLE(); 778 UNREACHABLE();
802 return; 779 return;
803 } 780 }
804 DartFrameIterator iterator(thread, 781 DartFrameIterator iterator(thread,
805 StackFrameIterator::kNoCrossThreadIteration); 782 StackFrameIterator::kNoCrossThreadIteration);
(...skipping 17 matching lines...) Expand all
823 return; 800 return;
824 } 801 }
825 const Error& error = Error::Handle(isolate->debugger()->PauseBreakpoint()); 802 const Error& error = Error::Handle(isolate->debugger()->PauseBreakpoint());
826 if (!error.IsNull()) { 803 if (!error.IsNull()) {
827 Exceptions::PropagateError(error); 804 Exceptions::PropagateError(error);
828 UNREACHABLE(); 805 UNREACHABLE();
829 } 806 }
830 } 807 }
831 #endif // !defined(TARGET_ARCH_DBC) 808 #endif // !defined(TARGET_ARCH_DBC)
832 809
833
834 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) { 810 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) {
835 if (!FLAG_support_debugger) { 811 if (!FLAG_support_debugger) {
836 UNREACHABLE(); 812 UNREACHABLE();
837 return; 813 return;
838 } 814 }
839 const Error& error = 815 const Error& error =
840 Error::Handle(zone, isolate->debugger()->PauseStepping()); 816 Error::Handle(zone, isolate->debugger()->PauseStepping());
841 if (!error.IsNull()) { 817 if (!error.IsNull()) {
842 Exceptions::PropagateError(error); 818 Exceptions::PropagateError(error);
843 UNREACHABLE(); 819 UNREACHABLE();
844 } 820 }
845 } 821 }
846 822
847
848 // An instance call of the form o.f(...) could not be resolved. Check if 823 // An instance call of the form o.f(...) could not be resolved. Check if
849 // there is a getter with the same name. If so, invoke it. If the value is 824 // there is a getter with the same name. If so, invoke it. If the value is
850 // a closure, invoke it with the given arguments. If the value is a 825 // a closure, invoke it with the given arguments. If the value is a
851 // non-closure, attempt to invoke "call" on it. 826 // non-closure, attempt to invoke "call" on it.
852 static bool ResolveCallThroughGetter(const Instance& receiver, 827 static bool ResolveCallThroughGetter(const Instance& receiver,
853 const Class& receiver_class, 828 const Class& receiver_class,
854 const String& target_name, 829 const String& target_name,
855 const Array& arguments_descriptor, 830 const Array& arguments_descriptor,
856 Function* result) { 831 Function* result) {
857 // 1. Check if there is a getter with the same name. 832 // 1. Check if there is a getter with the same name.
(...skipping 16 matching lines...) Expand all
874 if (FLAG_trace_ic) { 849 if (FLAG_trace_ic) {
875 OS::PrintErr( 850 OS::PrintErr(
876 "InvokeField IC miss: adding <%s> id:%" Pd " -> <%s>\n", 851 "InvokeField IC miss: adding <%s> id:%" Pd " -> <%s>\n",
877 Class::Handle(receiver.clazz()).ToCString(), receiver.GetClassId(), 852 Class::Handle(receiver.clazz()).ToCString(), receiver.GetClassId(),
878 target_function.IsNull() ? "null" : target_function.ToCString()); 853 target_function.IsNull() ? "null" : target_function.ToCString());
879 } 854 }
880 *result = target_function.raw(); 855 *result = target_function.raw();
881 return true; 856 return true;
882 } 857 }
883 858
884
885 // Handle other invocations (implicit closures, noSuchMethod). 859 // Handle other invocations (implicit closures, noSuchMethod).
886 RawFunction* InlineCacheMissHelper(const Instance& receiver, 860 RawFunction* InlineCacheMissHelper(const Instance& receiver,
887 const Array& args_descriptor, 861 const Array& args_descriptor,
888 const String& target_name) { 862 const String& target_name) {
889 const Class& receiver_class = Class::Handle(receiver.clazz()); 863 const Class& receiver_class = Class::Handle(receiver.clazz());
890 864
891 Function& result = Function::Handle(); 865 Function& result = Function::Handle();
892 if (!ResolveCallThroughGetter(receiver, receiver_class, target_name, 866 if (!ResolveCallThroughGetter(receiver, receiver_class, target_name,
893 args_descriptor, &result)) { 867 args_descriptor, &result)) {
894 ArgumentsDescriptor desc(args_descriptor); 868 ArgumentsDescriptor desc(args_descriptor);
895 const Function& target_function = 869 const Function& target_function =
896 Function::Handle(receiver_class.GetInvocationDispatcher( 870 Function::Handle(receiver_class.GetInvocationDispatcher(
897 target_name, args_descriptor, RawFunction::kNoSuchMethodDispatcher, 871 target_name, args_descriptor, RawFunction::kNoSuchMethodDispatcher,
898 FLAG_lazy_dispatchers)); 872 FLAG_lazy_dispatchers));
899 if (FLAG_trace_ic) { 873 if (FLAG_trace_ic) {
900 OS::PrintErr( 874 OS::PrintErr(
901 "NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n", 875 "NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n",
902 Class::Handle(receiver.clazz()).ToCString(), receiver.GetClassId(), 876 Class::Handle(receiver.clazz()).ToCString(), receiver.GetClassId(),
903 target_function.IsNull() ? "null" : target_function.ToCString()); 877 target_function.IsNull() ? "null" : target_function.ToCString());
904 } 878 }
905 result = target_function.raw(); 879 result = target_function.raw();
906 } 880 }
907 // May be null if --no-lazy-dispatchers, in which case dispatch will be 881 // May be null if --no-lazy-dispatchers, in which case dispatch will be
908 // handled by InvokeNoSuchMethodDispatcher. 882 // handled by InvokeNoSuchMethodDispatcher.
909 ASSERT(!result.IsNull() || !FLAG_lazy_dispatchers); 883 ASSERT(!result.IsNull() || !FLAG_lazy_dispatchers);
910 return result.raw(); 884 return result.raw();
911 } 885 }
912 886
913
914 // Perform the subtype and return constant function based on the result. 887 // Perform the subtype and return constant function based on the result.
915 static RawFunction* ComputeTypeCheckTarget(const Instance& receiver, 888 static RawFunction* ComputeTypeCheckTarget(const Instance& receiver,
916 const AbstractType& type, 889 const AbstractType& type,
917 const ArgumentsDescriptor& desc) { 890 const ArgumentsDescriptor& desc) {
918 Error& error = Error::Handle(); 891 Error& error = Error::Handle();
919 bool result = receiver.IsInstanceOf(type, Object::null_type_arguments(), 892 bool result = receiver.IsInstanceOf(type, Object::null_type_arguments(),
920 Object::null_type_arguments(), &error); 893 Object::null_type_arguments(), &error);
921 ASSERT(error.IsNull()); 894 ASSERT(error.IsNull());
922 ObjectStore* store = Isolate::Current()->object_store(); 895 ObjectStore* store = Isolate::Current()->object_store();
923 const Function& target = 896 const Function& target =
924 Function::Handle(result ? store->simple_instance_of_true_function() 897 Function::Handle(result ? store->simple_instance_of_true_function()
925 : store->simple_instance_of_false_function()); 898 : store->simple_instance_of_false_function());
926 ASSERT(!target.IsNull()); 899 ASSERT(!target.IsNull());
927 return target.raw(); 900 return target.raw();
928 } 901 }
929 902
930
931 static RawFunction* InlineCacheMissHandler( 903 static RawFunction* InlineCacheMissHandler(
932 const GrowableArray<const Instance*>& args, // Checked arguments only. 904 const GrowableArray<const Instance*>& args, // Checked arguments only.
933 const ICData& ic_data) { 905 const ICData& ic_data) {
934 const Instance& receiver = *args[0]; 906 const Instance& receiver = *args[0];
935 ArgumentsDescriptor arguments_descriptor( 907 ArgumentsDescriptor arguments_descriptor(
936 Array::Handle(ic_data.arguments_descriptor())); 908 Array::Handle(ic_data.arguments_descriptor()));
937 String& function_name = String::Handle(ic_data.target_name()); 909 String& function_name = String::Handle(ic_data.target_name());
938 ASSERT(function_name.IsSymbol()); 910 ASSERT(function_name.IsSymbol());
939 911
940 Function& target_function = Function::Handle( 912 Function& target_function = Function::Handle(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 "' " 963 "' "
992 "adding <%s> id:%" Pd " -> <%s>\n", 964 "adding <%s> id:%" Pd " -> <%s>\n",
993 args.length(), caller_frame->pc(), 965 args.length(), caller_frame->pc(),
994 Class::Handle(receiver.clazz()).ToCString(), 966 Class::Handle(receiver.clazz()).ToCString(),
995 receiver.GetClassId(), target_function.ToCString()); 967 receiver.GetClassId(), target_function.ToCString());
996 } 968 }
997 } 969 }
998 return target_function.raw(); 970 return target_function.raw();
999 } 971 }
1000 972
1001
1002 // Handles inline cache misses by updating the IC data array of the call site. 973 // Handles inline cache misses by updating the IC data array of the call site.
1003 // Arg0: Receiver object. 974 // Arg0: Receiver object.
1004 // Arg1: IC data object. 975 // Arg1: IC data object.
1005 // Returns: target function with compiled code or null. 976 // Returns: target function with compiled code or null.
1006 // Modifies the instance call to hold the updated IC data array. 977 // Modifies the instance call to hold the updated IC data array.
1007 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) { 978 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) {
1008 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); 979 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
1009 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); 980 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
1010 GrowableArray<const Instance*> args(1); 981 GrowableArray<const Instance*> args(1);
1011 args.Add(&receiver); 982 args.Add(&receiver);
1012 const Function& result = 983 const Function& result =
1013 Function::Handle(InlineCacheMissHandler(args, ic_data)); 984 Function::Handle(InlineCacheMissHandler(args, ic_data));
1014 arguments.SetReturn(result); 985 arguments.SetReturn(result);
1015 } 986 }
1016 987
1017
1018 // Handles inline cache misses by updating the IC data array of the call site. 988 // Handles inline cache misses by updating the IC data array of the call site.
1019 // Arg0: Receiver object. 989 // Arg0: Receiver object.
1020 // Arg1: Argument after receiver. 990 // Arg1: Argument after receiver.
1021 // Arg2: IC data object. 991 // Arg2: IC data object.
1022 // Returns: target function with compiled code or null. 992 // Returns: target function with compiled code or null.
1023 // Modifies the instance call to hold the updated IC data array. 993 // Modifies the instance call to hold the updated IC data array.
1024 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 3) { 994 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 3) {
1025 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); 995 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
1026 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1)); 996 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1));
1027 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); 997 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2));
1028 GrowableArray<const Instance*> args(2); 998 GrowableArray<const Instance*> args(2);
1029 args.Add(&receiver); 999 args.Add(&receiver);
1030 args.Add(&other); 1000 args.Add(&other);
1031 const Function& result = 1001 const Function& result =
1032 Function::Handle(InlineCacheMissHandler(args, ic_data)); 1002 Function::Handle(InlineCacheMissHandler(args, ic_data));
1033 arguments.SetReturn(result); 1003 arguments.SetReturn(result);
1034 } 1004 }
1035 1005
1036
1037 // Handles a static call in unoptimized code that has one argument type not 1006 // Handles a static call in unoptimized code that has one argument type not
1038 // seen before. Compile the target if necessary and update the ICData. 1007 // seen before. Compile the target if necessary and update the ICData.
1039 // Arg0: argument. 1008 // Arg0: argument.
1040 // Arg1: IC data object. 1009 // Arg1: IC data object.
1041 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerOneArg, 2) { 1010 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerOneArg, 2) {
1042 const Instance& arg = Instance::CheckedHandle(arguments.ArgAt(0)); 1011 const Instance& arg = Instance::CheckedHandle(arguments.ArgAt(0));
1043 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); 1012 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
1044 // IC data for static call is prepopulated with the statically known target. 1013 // IC data for static call is prepopulated with the statically known target.
1045 ASSERT(ic_data.NumberOfChecksIs(1)); 1014 ASSERT(ic_data.NumberOfChecksIs(1));
1046 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); 1015 const Function& target = Function::Handle(ic_data.GetTargetAt(0));
1047 target.EnsureHasCode(); 1016 target.EnsureHasCode();
1048 ASSERT(!target.IsNull() && target.HasCode()); 1017 ASSERT(!target.IsNull() && target.HasCode());
1049 ic_data.AddReceiverCheck(arg.GetClassId(), target, 1); 1018 ic_data.AddReceiverCheck(arg.GetClassId(), target, 1);
1050 if (FLAG_trace_ic) { 1019 if (FLAG_trace_ic) {
1051 DartFrameIterator iterator(thread, 1020 DartFrameIterator iterator(thread,
1052 StackFrameIterator::kNoCrossThreadIteration); 1021 StackFrameIterator::kNoCrossThreadIteration);
1053 StackFrame* caller_frame = iterator.NextFrame(); 1022 StackFrame* caller_frame = iterator.NextFrame();
1054 ASSERT(caller_frame != NULL); 1023 ASSERT(caller_frame != NULL);
1055 OS::PrintErr("StaticCallMissHandler at %#" Px " target %s (%" Pd ")\n", 1024 OS::PrintErr("StaticCallMissHandler at %#" Px " target %s (%" Pd ")\n",
1056 caller_frame->pc(), target.ToCString(), arg.GetClassId()); 1025 caller_frame->pc(), target.ToCString(), arg.GetClassId());
1057 } 1026 }
1058 arguments.SetReturn(target); 1027 arguments.SetReturn(target);
1059 } 1028 }
1060 1029
1061
1062 // Handles a static call in unoptimized code that has two argument types not 1030 // Handles a static call in unoptimized code that has two argument types not
1063 // seen before. Compile the target if necessary and update the ICData. 1031 // seen before. Compile the target if necessary and update the ICData.
1064 // Arg0: argument 0. 1032 // Arg0: argument 0.
1065 // Arg1: argument 1. 1033 // Arg1: argument 1.
1066 // Arg2: IC data object. 1034 // Arg2: IC data object.
1067 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) { 1035 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) {
1068 const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0)); 1036 const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0));
1069 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); 1037 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1));
1070 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); 1038 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2));
1071 // IC data for static call is prepopulated with the statically known target. 1039 // IC data for static call is prepopulated with the statically known target.
1072 ASSERT(!ic_data.NumberOfChecksIs(0)); 1040 ASSERT(!ic_data.NumberOfChecksIs(0));
1073 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); 1041 const Function& target = Function::Handle(ic_data.GetTargetAt(0));
1074 target.EnsureHasCode(); 1042 target.EnsureHasCode();
1075 GrowableArray<intptr_t> cids(2); 1043 GrowableArray<intptr_t> cids(2);
1076 cids.Add(arg0.GetClassId()); 1044 cids.Add(arg0.GetClassId());
1077 cids.Add(arg1.GetClassId()); 1045 cids.Add(arg1.GetClassId());
1078 ic_data.AddCheck(cids, target); 1046 ic_data.AddCheck(cids, target);
1079 if (FLAG_trace_ic) { 1047 if (FLAG_trace_ic) {
1080 DartFrameIterator iterator(thread, 1048 DartFrameIterator iterator(thread,
1081 StackFrameIterator::kNoCrossThreadIteration); 1049 StackFrameIterator::kNoCrossThreadIteration);
1082 StackFrame* caller_frame = iterator.NextFrame(); 1050 StackFrame* caller_frame = iterator.NextFrame();
1083 ASSERT(caller_frame != NULL); 1051 ASSERT(caller_frame != NULL);
1084 OS::PrintErr("StaticCallMissHandler at %#" Px " target %s (%" Pd ", %" Pd 1052 OS::PrintErr("StaticCallMissHandler at %#" Px " target %s (%" Pd ", %" Pd
1085 ")\n", 1053 ")\n",
1086 caller_frame->pc(), target.ToCString(), cids[0], cids[1]); 1054 caller_frame->pc(), target.ToCString(), cids[0], cids[1]);
1087 } 1055 }
1088 arguments.SetReturn(target); 1056 arguments.SetReturn(target);
1089 } 1057 }
1090 1058
1091
1092 #if !defined(TARGET_ARCH_DBC) 1059 #if !defined(TARGET_ARCH_DBC)
1093 static bool IsSingleTarget(Isolate* isolate, 1060 static bool IsSingleTarget(Isolate* isolate,
1094 Zone* zone, 1061 Zone* zone,
1095 intptr_t lower_cid, 1062 intptr_t lower_cid,
1096 intptr_t upper_cid, 1063 intptr_t upper_cid,
1097 const Function& target, 1064 const Function& target,
1098 const String& name) { 1065 const String& name) {
1099 Class& cls = Class::Handle(zone); 1066 Class& cls = Class::Handle(zone);
1100 ClassTable* table = isolate->class_table(); 1067 ClassTable* table = isolate->class_table();
1101 Function& other_target = Function::Handle(zone); 1068 Function& other_target = Function::Handle(zone);
1102 for (intptr_t cid = lower_cid; cid <= upper_cid; cid++) { 1069 for (intptr_t cid = lower_cid; cid <= upper_cid; cid++) {
1103 if (!table->HasValidClassAt(cid)) continue; 1070 if (!table->HasValidClassAt(cid)) continue;
1104 cls = table->At(cid); 1071 cls = table->At(cid);
1105 if (cls.is_abstract()) continue; 1072 if (cls.is_abstract()) continue;
1106 if (!cls.is_allocated()) continue; 1073 if (!cls.is_allocated()) continue;
1107 other_target = 1074 other_target =
1108 Resolver::ResolveDynamicAnyArgs(zone, cls, name, false /* allow_add */); 1075 Resolver::ResolveDynamicAnyArgs(zone, cls, name, false /* allow_add */);
1109 if (other_target.raw() != target.raw()) { 1076 if (other_target.raw() != target.raw()) {
1110 return false; 1077 return false;
1111 } 1078 }
1112 } 1079 }
1113 return true; 1080 return true;
1114 } 1081 }
1115 #endif 1082 #endif
1116 1083
1117
1118 // Handle a miss of a single target cache. 1084 // Handle a miss of a single target cache.
1119 // Arg0: Receiver. 1085 // Arg0: Receiver.
1120 // Returns: the ICData used to continue with a polymorphic call. 1086 // Returns: the ICData used to continue with a polymorphic call.
1121 DEFINE_RUNTIME_ENTRY(SingleTargetMiss, 1) { 1087 DEFINE_RUNTIME_ENTRY(SingleTargetMiss, 1) {
1122 #if defined(TARGET_ARCH_DBC) 1088 #if defined(TARGET_ARCH_DBC)
1123 // DBC does not use switchable calls. 1089 // DBC does not use switchable calls.
1124 UNREACHABLE(); 1090 UNREACHABLE();
1125 #else 1091 #else
1126 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); 1092 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
1127 1093
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 ASSERT(!Isolate::Current()->compilation_allowed()); 1164 ASSERT(!Isolate::Current()->compilation_allowed());
1199 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, ic_data, 1165 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, ic_data,
1200 stub); 1166 stub);
1201 1167
1202 // Return the ICData. The single target stub will jump to continue in the 1168 // Return the ICData. The single target stub will jump to continue in the
1203 // IC call stub. 1169 // IC call stub.
1204 arguments.SetReturn(ic_data); 1170 arguments.SetReturn(ic_data);
1205 #endif 1171 #endif
1206 } 1172 }
1207 1173
1208
1209 DEFINE_RUNTIME_ENTRY(UnlinkedCall, 2) { 1174 DEFINE_RUNTIME_ENTRY(UnlinkedCall, 2) {
1210 #if defined(TARGET_ARCH_DBC) 1175 #if defined(TARGET_ARCH_DBC)
1211 // DBC does not use switchable calls. 1176 // DBC does not use switchable calls.
1212 UNREACHABLE(); 1177 UNREACHABLE();
1213 #else 1178 #else
1214 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); 1179 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
1215 const UnlinkedCall& unlinked = 1180 const UnlinkedCall& unlinked =
1216 UnlinkedCall::CheckedHandle(zone, arguments.ArgAt(1)); 1181 UnlinkedCall::CheckedHandle(zone, arguments.ArgAt(1));
1217 1182
1218 DartFrameIterator iterator(thread, 1183 DartFrameIterator iterator(thread,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 ASSERT(!Isolate::Current()->compilation_allowed()); 1230 ASSERT(!Isolate::Current()->compilation_allowed());
1266 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, ic_data, 1231 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, ic_data,
1267 stub); 1232 stub);
1268 1233
1269 // Return the ICData. The miss stub will jump to continue in the IC lookup 1234 // Return the ICData. The miss stub will jump to continue in the IC lookup
1270 // stub. 1235 // stub.
1271 arguments.SetReturn(ic_data); 1236 arguments.SetReturn(ic_data);
1272 #endif // !DBC 1237 #endif // !DBC
1273 } 1238 }
1274 1239
1275
1276 // Handle a miss of a megamorphic cache. 1240 // Handle a miss of a megamorphic cache.
1277 // Arg0: Receiver. 1241 // Arg0: Receiver.
1278 // Returns: the ICData used to continue with a polymorphic call. 1242 // Returns: the ICData used to continue with a polymorphic call.
1279 DEFINE_RUNTIME_ENTRY(MonomorphicMiss, 1) { 1243 DEFINE_RUNTIME_ENTRY(MonomorphicMiss, 1) {
1280 #if defined(TARGET_ARCH_DBC) 1244 #if defined(TARGET_ARCH_DBC)
1281 // DBC does not use switchable calls. 1245 // DBC does not use switchable calls.
1282 UNREACHABLE(); 1246 UNREACHABLE();
1283 #else 1247 #else
1284 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); 1248 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
1285 1249
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 ASSERT(!Isolate::Current()->compilation_allowed()); 1328 ASSERT(!Isolate::Current()->compilation_allowed());
1365 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, ic_data, 1329 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, ic_data,
1366 stub); 1330 stub);
1367 1331
1368 // Return the ICData. The miss stub will jump to continue in the IC lookup 1332 // Return the ICData. The miss stub will jump to continue in the IC lookup
1369 // stub. 1333 // stub.
1370 arguments.SetReturn(ic_data); 1334 arguments.SetReturn(ic_data);
1371 #endif // !defined(TARGET_ARCH_DBC) 1335 #endif // !defined(TARGET_ARCH_DBC)
1372 } 1336 }
1373 1337
1374
1375 // Handle a miss of a megamorphic cache. 1338 // Handle a miss of a megamorphic cache.
1376 // Arg0: Receiver. 1339 // Arg0: Receiver.
1377 // Arg1: ICData or MegamorphicCache. 1340 // Arg1: ICData or MegamorphicCache.
1378 // Arg2: Arguments descriptor array. 1341 // Arg2: Arguments descriptor array.
1379 // Returns: target function to call. 1342 // Returns: target function to call.
1380 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) { 1343 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) {
1381 #if defined(TARGET_ARCH_DBC) 1344 #if defined(TARGET_ARCH_DBC)
1382 // DBC does not use megamorphic calls right now. 1345 // DBC does not use megamorphic calls right now.
1383 UNREACHABLE(); 1346 UNREACHABLE();
1384 #else 1347 #else
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 const MegamorphicCache& cache = MegamorphicCache::Cast(ic_data_or_cache); 1429 const MegamorphicCache& cache = MegamorphicCache::Cast(ic_data_or_cache);
1467 // Insert function found into cache and return it. 1430 // Insert function found into cache and return it.
1468 cache.EnsureCapacity(); 1431 cache.EnsureCapacity();
1469 const Smi& class_id = Smi::Handle(zone, Smi::New(cls.id())); 1432 const Smi& class_id = Smi::Handle(zone, Smi::New(cls.id()));
1470 cache.Insert(class_id, target_function); 1433 cache.Insert(class_id, target_function);
1471 } 1434 }
1472 arguments.SetReturn(target_function); 1435 arguments.SetReturn(target_function);
1473 #endif // !defined(TARGET_ARCH_DBC) 1436 #endif // !defined(TARGET_ARCH_DBC)
1474 } 1437 }
1475 1438
1476
1477 // Invoke appropriate noSuchMethod or closure from getter. 1439 // Invoke appropriate noSuchMethod or closure from getter.
1478 // Arg0: receiver 1440 // Arg0: receiver
1479 // Arg1: ICData or MegamorphicCache 1441 // Arg1: ICData or MegamorphicCache
1480 // Arg2: arguments descriptor array 1442 // Arg2: arguments descriptor array
1481 // Arg3: arguments array 1443 // Arg3: arguments array
1482 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) { 1444 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) {
1483 ASSERT(!FLAG_lazy_dispatchers); 1445 ASSERT(!FLAG_lazy_dispatchers);
1484 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); 1446 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
1485 const Object& ic_data_or_cache = Object::Handle(zone, arguments.ArgAt(1)); 1447 const Object& ic_data_or_cache = Object::Handle(zone, arguments.ArgAt(1));
1486 const Array& orig_arguments_desc = 1448 const Array& orig_arguments_desc =
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 cls = cls.SuperClass(); 1572 cls = cls.SuperClass();
1611 } 1573 }
1612 } 1574 }
1613 1575
1614 NO_SUCH_METHOD(); 1576 NO_SUCH_METHOD();
1615 1577
1616 #undef NO_SUCH_METHOD 1578 #undef NO_SUCH_METHOD
1617 #undef CLOSURIZE 1579 #undef CLOSURIZE
1618 } 1580 }
1619 1581
1620
1621 // Invoke appropriate noSuchMethod function. 1582 // Invoke appropriate noSuchMethod function.
1622 // Arg0: receiver (closure object) 1583 // Arg0: receiver (closure object)
1623 // Arg1: arguments descriptor array. 1584 // Arg1: arguments descriptor array.
1624 // Arg2: arguments array. 1585 // Arg2: arguments array.
1625 DEFINE_RUNTIME_ENTRY(InvokeClosureNoSuchMethod, 3) { 1586 DEFINE_RUNTIME_ENTRY(InvokeClosureNoSuchMethod, 3) {
1626 const Closure& receiver = Closure::CheckedHandle(arguments.ArgAt(0)); 1587 const Closure& receiver = Closure::CheckedHandle(arguments.ArgAt(0));
1627 const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(1)); 1588 const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(1));
1628 const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(2)); 1589 const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(2));
1629 1590
1630 // For closure the function name is always 'call'. Replace it with the 1591 // For closure the function name is always 'call'. Replace it with the
1631 // name of the closurized function so that exception contains more 1592 // name of the closurized function so that exception contains more
1632 // relevant information. 1593 // relevant information.
1633 const Function& function = Function::Handle(receiver.function()); 1594 const Function& function = Function::Handle(receiver.function());
1634 const String& original_function_name = 1595 const String& original_function_name =
1635 String::Handle(function.QualifiedUserVisibleName()); 1596 String::Handle(function.QualifiedUserVisibleName());
1636 const Object& result = Object::Handle(DartEntry::InvokeNoSuchMethod( 1597 const Object& result = Object::Handle(DartEntry::InvokeNoSuchMethod(
1637 receiver, original_function_name, orig_arguments, orig_arguments_desc)); 1598 receiver, original_function_name, orig_arguments, orig_arguments_desc));
1638 CheckResultError(result); 1599 CheckResultError(result);
1639 arguments.SetReturn(result); 1600 arguments.SetReturn(result);
1640 } 1601 }
1641 1602
1642
1643 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { 1603 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) {
1644 #if defined(USING_SIMULATOR) 1604 #if defined(USING_SIMULATOR)
1645 uword stack_pos = Simulator::Current()->get_sp(); 1605 uword stack_pos = Simulator::Current()->get_sp();
1646 #else 1606 #else
1647 uword stack_pos = Thread::GetCurrentStackPointer(); 1607 uword stack_pos = Thread::GetCurrentStackPointer();
1648 #endif 1608 #endif
1649 // Always clear the stack overflow flags. They are meant for this 1609 // Always clear the stack overflow flags. They are meant for this
1650 // particular stack overflow runtime call and are not meant to 1610 // particular stack overflow runtime call and are not meant to
1651 // persist. 1611 // persist.
1652 uword stack_overflow_flags = thread->GetAndClearStackOverflowFlags(); 1612 uword stack_overflow_flags = thread->GetAndClearStackOverflowFlags();
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1821 if (!result.IsNull()) { 1781 if (!result.IsNull()) {
1822 const Code& code = Code::Cast(result); 1782 const Code& code = Code::Cast(result);
1823 uword optimized_entry = 1783 uword optimized_entry =
1824 Instructions::UncheckedEntryPoint(code.instructions()); 1784 Instructions::UncheckedEntryPoint(code.instructions());
1825 frame->set_pc(optimized_entry); 1785 frame->set_pc(optimized_entry);
1826 frame->set_pc_marker(code.raw()); 1786 frame->set_pc_marker(code.raw());
1827 } 1787 }
1828 } 1788 }
1829 } 1789 }
1830 1790
1831
1832 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { 1791 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) {
1833 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); 1792 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0));
1834 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); 1793 const Function& function = Function::CheckedHandle(arguments.ArgAt(1));
1835 DartFrameIterator iterator(thread, 1794 DartFrameIterator iterator(thread,
1836 StackFrameIterator::kNoCrossThreadIteration); 1795 StackFrameIterator::kNoCrossThreadIteration);
1837 StackFrame* frame = iterator.NextFrame(); 1796 StackFrame* frame = iterator.NextFrame();
1838 ASSERT(frame != NULL); 1797 ASSERT(frame != NULL);
1839 OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd 1798 OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd
1840 " %s\n", 1799 " %s\n",
1841 frame->pc(), ic_data.raw(), function.usage_counter(), 1800 frame->pc(), ic_data.raw(), function.usage_counter(),
1842 ic_data.NumberOfChecks(), function.ToFullyQualifiedCString()); 1801 ic_data.NumberOfChecks(), function.ToFullyQualifiedCString());
1843 } 1802 }
1844 1803
1845
1846 // This is called from function that needs to be optimized. 1804 // This is called from function that needs to be optimized.
1847 // The requesting function can be already optimized (reoptimization). 1805 // The requesting function can be already optimized (reoptimization).
1848 // Returns the Code object where to continue execution. 1806 // Returns the Code object where to continue execution.
1849 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { 1807 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
1850 #if !defined(DART_PRECOMPILED_RUNTIME) 1808 #if !defined(DART_PRECOMPILED_RUNTIME)
1851 const Function& function = Function::CheckedHandle(zone, arguments.ArgAt(0)); 1809 const Function& function = Function::CheckedHandle(zone, arguments.ArgAt(0));
1852 ASSERT(!function.IsNull()); 1810 ASSERT(!function.IsNull());
1853 ASSERT(function.HasCode()); 1811 ASSERT(function.HasCode());
1854 1812
1855 if (Compiler::CanOptimizeFunction(thread, function)) { 1813 if (Compiler::CanOptimizeFunction(thread, function)) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1902 if (result.IsError()) { 1860 if (result.IsError()) {
1903 Exceptions::PropagateError(Error::Cast(result)); 1861 Exceptions::PropagateError(Error::Cast(result));
1904 } 1862 }
1905 } 1863 }
1906 arguments.SetReturn(function); 1864 arguments.SetReturn(function);
1907 #else 1865 #else
1908 UNREACHABLE(); 1866 UNREACHABLE();
1909 #endif // !DART_PRECOMPILED_RUNTIME 1867 #endif // !DART_PRECOMPILED_RUNTIME
1910 } 1868 }
1911 1869
1912
1913 // The caller must be a static call in a Dart frame, or an entry frame. 1870 // The caller must be a static call in a Dart frame, or an entry frame.
1914 // Patch static call to point to valid code's entry point. 1871 // Patch static call to point to valid code's entry point.
1915 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { 1872 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) {
1916 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, thread, 1873 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, thread,
1917 StackFrameIterator::kNoCrossThreadIteration); 1874 StackFrameIterator::kNoCrossThreadIteration);
1918 StackFrame* frame = iterator.NextFrame(); 1875 StackFrame* frame = iterator.NextFrame();
1919 ASSERT(frame != NULL); 1876 ASSERT(frame != NULL);
1920 while (frame->IsStubFrame() || frame->IsExitFrame()) { 1877 while (frame->IsStubFrame() || frame->IsExitFrame()) {
1921 frame = iterator.NextFrame(); 1878 frame = iterator.NextFrame();
1922 ASSERT(frame != NULL); 1879 ASSERT(frame != NULL);
(...skipping 17 matching lines...) Expand all
1940 OS::PrintErr("FixCallersTarget: caller %#" Px 1897 OS::PrintErr("FixCallersTarget: caller %#" Px
1941 " " 1898 " "
1942 "target '%s' -> %#" Px "\n", 1899 "target '%s' -> %#" Px "\n",
1943 frame->pc(), target_function.ToFullyQualifiedCString(), 1900 frame->pc(), target_function.ToFullyQualifiedCString(),
1944 current_target_code.UncheckedEntryPoint()); 1901 current_target_code.UncheckedEntryPoint());
1945 } 1902 }
1946 ASSERT(!current_target_code.IsDisabled()); 1903 ASSERT(!current_target_code.IsDisabled());
1947 arguments.SetReturn(current_target_code); 1904 arguments.SetReturn(current_target_code);
1948 } 1905 }
1949 1906
1950
1951 // The caller tried to allocate an instance via an invalidated allocation 1907 // The caller tried to allocate an instance via an invalidated allocation
1952 // stub. 1908 // stub.
1953 DEFINE_RUNTIME_ENTRY(FixAllocationStubTarget, 0) { 1909 DEFINE_RUNTIME_ENTRY(FixAllocationStubTarget, 0) {
1954 #if !defined(DART_PRECOMPILED_RUNTIME) 1910 #if !defined(DART_PRECOMPILED_RUNTIME)
1955 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, thread, 1911 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, thread,
1956 StackFrameIterator::kNoCrossThreadIteration); 1912 StackFrameIterator::kNoCrossThreadIteration);
1957 StackFrame* frame = iterator.NextFrame(); 1913 StackFrame* frame = iterator.NextFrame();
1958 ASSERT(frame != NULL); 1914 ASSERT(frame != NULL);
1959 while (frame->IsStubFrame() || frame->IsExitFrame()) { 1915 while (frame->IsStubFrame() || frame->IsExitFrame()) {
1960 frame = iterator.NextFrame(); 1916 frame = iterator.NextFrame();
(...skipping 23 matching lines...) Expand all
1984 " -> %#" Px "\n", 1940 " -> %#" Px "\n",
1985 frame->pc(), alloc_class.ToCString(), 1941 frame->pc(), alloc_class.ToCString(),
1986 alloc_stub.UncheckedEntryPoint()); 1942 alloc_stub.UncheckedEntryPoint());
1987 } 1943 }
1988 arguments.SetReturn(alloc_stub); 1944 arguments.SetReturn(alloc_stub);
1989 #else 1945 #else
1990 UNREACHABLE(); 1946 UNREACHABLE();
1991 #endif 1947 #endif
1992 } 1948 }
1993 1949
1994
1995 const char* DeoptReasonToCString(ICData::DeoptReasonId deopt_reason) { 1950 const char* DeoptReasonToCString(ICData::DeoptReasonId deopt_reason) {
1996 switch (deopt_reason) { 1951 switch (deopt_reason) {
1997 #define DEOPT_REASON_TO_TEXT(name) \ 1952 #define DEOPT_REASON_TO_TEXT(name) \
1998 case ICData::kDeopt##name: \ 1953 case ICData::kDeopt##name: \
1999 return #name; 1954 return #name;
2000 DEOPT_REASONS(DEOPT_REASON_TO_TEXT) 1955 DEOPT_REASONS(DEOPT_REASON_TO_TEXT)
2001 #undef DEOPT_REASON_TO_TEXT 1956 #undef DEOPT_REASON_TO_TEXT
2002 default: 1957 default:
2003 UNREACHABLE(); 1958 UNREACHABLE();
2004 return ""; 1959 return "";
2005 } 1960 }
2006 } 1961 }
2007 1962
2008
2009 void DeoptimizeAt(const Code& optimized_code, StackFrame* frame) { 1963 void DeoptimizeAt(const Code& optimized_code, StackFrame* frame) {
2010 ASSERT(optimized_code.is_optimized()); 1964 ASSERT(optimized_code.is_optimized());
2011 Thread* thread = Thread::Current(); 1965 Thread* thread = Thread::Current();
2012 Zone* zone = thread->zone(); 1966 Zone* zone = thread->zone();
2013 const Function& function = Function::Handle(zone, optimized_code.function()); 1967 const Function& function = Function::Handle(zone, optimized_code.function());
2014 const Error& error = 1968 const Error& error =
2015 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function)); 1969 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function));
2016 if (!error.IsNull()) { 1970 if (!error.IsNull()) {
2017 Exceptions::PropagateError(error); 1971 Exceptions::PropagateError(error);
2018 } 1972 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n", 2024 THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n",
2071 frame->fp(), deopt_pc); 2025 frame->fp(), deopt_pc);
2072 } 2026 }
2073 } 2027 }
2074 #endif // !DBC 2028 #endif // !DBC
2075 2029
2076 // Mark code as dead (do not GC its embedded objects). 2030 // Mark code as dead (do not GC its embedded objects).
2077 optimized_code.set_is_alive(false); 2031 optimized_code.set_is_alive(false);
2078 } 2032 }
2079 2033
2080
2081 // Currently checks only that all optimized frames have kDeoptIndex 2034 // Currently checks only that all optimized frames have kDeoptIndex
2082 // and unoptimized code has the kDeoptAfter. 2035 // and unoptimized code has the kDeoptAfter.
2083 void DeoptimizeFunctionsOnStack() { 2036 void DeoptimizeFunctionsOnStack() {
2084 DartFrameIterator iterator(Thread::Current(), 2037 DartFrameIterator iterator(Thread::Current(),
2085 StackFrameIterator::kNoCrossThreadIteration); 2038 StackFrameIterator::kNoCrossThreadIteration);
2086 StackFrame* frame = iterator.NextFrame(); 2039 StackFrame* frame = iterator.NextFrame();
2087 Code& optimized_code = Code::Handle(); 2040 Code& optimized_code = Code::Handle();
2088 while (frame != NULL) { 2041 while (frame != NULL) {
2089 optimized_code = frame->LookupDartCode(); 2042 optimized_code = frame->LookupDartCode();
2090 if (optimized_code.is_optimized()) { 2043 if (optimized_code.is_optimized()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 ASSERT(cpu_registers_copy != NULL); 2075 ASSERT(cpu_registers_copy != NULL);
2123 for (intptr_t i = 0; i < kNumberOfSavedCpuRegisters; i++) { 2076 for (intptr_t i = 0; i < kNumberOfSavedCpuRegisters; i++) {
2124 cpu_registers_copy[i] = 2077 cpu_registers_copy[i] =
2125 *reinterpret_cast<intptr_t*>(saved_registers_address); 2078 *reinterpret_cast<intptr_t*>(saved_registers_address);
2126 saved_registers_address += kWordSize; 2079 saved_registers_address += kWordSize;
2127 } 2080 }
2128 *cpu_registers = cpu_registers_copy; 2081 *cpu_registers = cpu_registers_copy;
2129 } 2082 }
2130 #endif 2083 #endif
2131 2084
2132
2133 // Copies saved registers and caller's frame into temporary buffers. 2085 // Copies saved registers and caller's frame into temporary buffers.
2134 // Returns the stack size of unoptimized frame. 2086 // Returns the stack size of unoptimized frame.
2135 // The calling code must be optimized, but its function may not have 2087 // The calling code must be optimized, but its function may not have
2136 // have optimized code if the code is OSR code, or if the code was invalidated 2088 // have optimized code if the code is OSR code, or if the code was invalidated
2137 // through class loading/finalization or field guard. 2089 // through class loading/finalization or field guard.
2138 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, 2090 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t,
2139 DeoptimizeCopyFrame, 2091 DeoptimizeCopyFrame,
2140 2, 2092 2,
2141 uword saved_registers_address, 2093 uword saved_registers_address,
2142 uword is_lazy_deopt) { 2094 uword is_lazy_deopt) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 2158
2207 // Stack size (FP - SP) in bytes. 2159 // Stack size (FP - SP) in bytes.
2208 return deopt_context->DestStackAdjustment() * kWordSize; 2160 return deopt_context->DestStackAdjustment() * kWordSize;
2209 #else 2161 #else
2210 UNREACHABLE(); 2162 UNREACHABLE();
2211 return 0; 2163 return 0;
2212 #endif // !DART_PRECOMPILED_RUNTIME 2164 #endif // !DART_PRECOMPILED_RUNTIME
2213 } 2165 }
2214 END_LEAF_RUNTIME_ENTRY 2166 END_LEAF_RUNTIME_ENTRY
2215 2167
2216
2217 // The stack has been adjusted to fit all values for unoptimized frame. 2168 // The stack has been adjusted to fit all values for unoptimized frame.
2218 // Fill the unoptimized frame. 2169 // Fill the unoptimized frame.
2219 DEFINE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, 1, uword last_fp) { 2170 DEFINE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, 1, uword last_fp) {
2220 #if !defined(DART_PRECOMPILED_RUNTIME) 2171 #if !defined(DART_PRECOMPILED_RUNTIME)
2221 Thread* thread = Thread::Current(); 2172 Thread* thread = Thread::Current();
2222 Isolate* isolate = thread->isolate(); 2173 Isolate* isolate = thread->isolate();
2223 StackZone zone(thread); 2174 StackZone zone(thread);
2224 HANDLESCOPE(thread); 2175 HANDLESCOPE(thread);
2225 2176
2226 DeoptContext* deopt_context = isolate->deopt_context(); 2177 DeoptContext* deopt_context = isolate->deopt_context();
(...skipping 22 matching lines...) Expand all
2249 2200
2250 deopt_context->set_dest_frame(caller_frame); 2201 deopt_context->set_dest_frame(caller_frame);
2251 deopt_context->FillDestFrame(); 2202 deopt_context->FillDestFrame();
2252 2203
2253 #else 2204 #else
2254 UNREACHABLE(); 2205 UNREACHABLE();
2255 #endif // !DART_PRECOMPILED_RUNTIME 2206 #endif // !DART_PRECOMPILED_RUNTIME
2256 } 2207 }
2257 END_LEAF_RUNTIME_ENTRY 2208 END_LEAF_RUNTIME_ENTRY
2258 2209
2259
2260 // This is the last step in the deoptimization, GC can occur. 2210 // This is the last step in the deoptimization, GC can occur.
2261 // Returns number of bytes to remove from the expression stack of the 2211 // Returns number of bytes to remove from the expression stack of the
2262 // bottom-most deoptimized frame. Those arguments were artificially injected 2212 // bottom-most deoptimized frame. Those arguments were artificially injected
2263 // under return address to keep them discoverable by GC that can occur during 2213 // under return address to keep them discoverable by GC that can occur during
2264 // materialization phase. 2214 // materialization phase.
2265 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) { 2215 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) {
2266 #if !defined(DART_PRECOMPILED_RUNTIME) 2216 #if !defined(DART_PRECOMPILED_RUNTIME)
2267 #if defined(DEBUG) 2217 #if defined(DEBUG)
2268 { 2218 {
2269 // We may rendezvous for a safepoint at entry or GC from the allocations 2219 // We may rendezvous for a safepoint at entry or GC from the allocations
2270 // below. Check the stack is walkable. 2220 // below. Check the stack is walkable.
2271 ValidateFrames(); 2221 ValidateFrames();
2272 } 2222 }
2273 #endif 2223 #endif
2274 DeoptContext* deopt_context = isolate->deopt_context(); 2224 DeoptContext* deopt_context = isolate->deopt_context();
2275 intptr_t deopt_arg_count = deopt_context->MaterializeDeferredObjects(); 2225 intptr_t deopt_arg_count = deopt_context->MaterializeDeferredObjects();
2276 isolate->set_deopt_context(NULL); 2226 isolate->set_deopt_context(NULL);
2277 delete deopt_context; 2227 delete deopt_context;
2278 2228
2279 // Return value tells deoptimization stub to remove the given number of bytes 2229 // Return value tells deoptimization stub to remove the given number of bytes
2280 // from the stack. 2230 // from the stack.
2281 arguments.SetReturn(Smi::Handle(Smi::New(deopt_arg_count * kWordSize))); 2231 arguments.SetReturn(Smi::Handle(Smi::New(deopt_arg_count * kWordSize)));
2282 #else 2232 #else
2283 UNREACHABLE(); 2233 UNREACHABLE();
2284 #endif // !DART_PRECOMPILED_RUNTIME 2234 #endif // !DART_PRECOMPILED_RUNTIME
2285 } 2235 }
2286 2236
2287
2288 DEFINE_RUNTIME_ENTRY(RewindPostDeopt, 0) { 2237 DEFINE_RUNTIME_ENTRY(RewindPostDeopt, 0) {
2289 #if !defined(DART_PRECOMPILED_RUNTIME) 2238 #if !defined(DART_PRECOMPILED_RUNTIME)
2290 #if !defined(PRODUCT) 2239 #if !defined(PRODUCT)
2291 isolate->debugger()->RewindPostDeopt(); 2240 isolate->debugger()->RewindPostDeopt();
2292 #endif // !PRODUCT 2241 #endif // !PRODUCT
2293 #endif // !DART_PRECOMPILED_RUNTIME 2242 #endif // !DART_PRECOMPILED_RUNTIME
2294 UNREACHABLE(); 2243 UNREACHABLE();
2295 } 2244 }
2296 2245
2297 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, 2246 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t,
2298 BigintCompare, 2247 BigintCompare,
2299 2, 2248 2,
2300 RawBigint* left, 2249 RawBigint* left,
2301 RawBigint* right) { 2250 RawBigint* right) {
2302 Thread* thread = Thread::Current(); 2251 Thread* thread = Thread::Current();
2303 StackZone zone(thread); 2252 StackZone zone(thread);
2304 HANDLESCOPE(thread); 2253 HANDLESCOPE(thread);
2305 const Bigint& big_left = Bigint::Handle(left); 2254 const Bigint& big_left = Bigint::Handle(left);
2306 const Bigint& big_right = Bigint::Handle(right); 2255 const Bigint& big_right = Bigint::Handle(right);
2307 return big_left.CompareWith(big_right); 2256 return big_left.CompareWith(big_right);
2308 } 2257 }
2309 END_LEAF_RUNTIME_ENTRY 2258 END_LEAF_RUNTIME_ENTRY
2310 2259
2311
2312 double DartModulo(double left, double right) { 2260 double DartModulo(double left, double right) {
2313 double remainder = fmod_ieee(left, right); 2261 double remainder = fmod_ieee(left, right);
2314 if (remainder == 0.0) { 2262 if (remainder == 0.0) {
2315 // We explicitly switch to the positive 0.0 (just in case it was negative). 2263 // We explicitly switch to the positive 0.0 (just in case it was negative).
2316 remainder = +0.0; 2264 remainder = +0.0;
2317 } else if (remainder < 0.0) { 2265 } else if (remainder < 0.0) {
2318 if (right < 0) { 2266 if (right < 0) {
2319 remainder -= right; 2267 remainder -= right;
2320 } else { 2268 } else {
2321 remainder += right; 2269 remainder += right;
2322 } 2270 }
2323 } 2271 }
2324 return remainder; 2272 return remainder;
2325 } 2273 }
2326 2274
2327
2328 // Update global type feedback recorded for a field recording the assignment 2275 // Update global type feedback recorded for a field recording the assignment
2329 // of the given value. 2276 // of the given value.
2330 // Arg0: Field object; 2277 // Arg0: Field object;
2331 // Arg1: Value that is being stored. 2278 // Arg1: Value that is being stored.
2332 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { 2279 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) {
2333 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); 2280 const Field& field = Field::CheckedHandle(arguments.ArgAt(0));
2334 const Object& value = Object::Handle(arguments.ArgAt(1)); 2281 const Object& value = Object::Handle(arguments.ArgAt(1));
2335 field.RecordStore(value); 2282 field.RecordStore(value);
2336 } 2283 }
2337 2284
2338
2339 DEFINE_RUNTIME_ENTRY(InitStaticField, 1) { 2285 DEFINE_RUNTIME_ENTRY(InitStaticField, 1) {
2340 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); 2286 const Field& field = Field::CheckedHandle(arguments.ArgAt(0));
2341 field.EvaluateInitializer(); 2287 field.EvaluateInitializer();
2342 } 2288 }
2343 2289
2344 // Use expected function signatures to help MSVC compiler resolve overloading. 2290 // Use expected function signatures to help MSVC compiler resolve overloading.
2345 typedef double (*UnaryMathCFunction)(double x); 2291 typedef double (*UnaryMathCFunction)(double x);
2346 typedef double (*BinaryMathCFunction)(double x, double y); 2292 typedef double (*BinaryMathCFunction)(double x, double y);
2347 2293
2348 DEFINE_RAW_LEAF_RUNTIME_ENTRY( 2294 DEFINE_RAW_LEAF_RUNTIME_ENTRY(
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2419 true /* is_float */, 2365 true /* is_float */,
2420 reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&tan))); 2366 reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&tan)));
2421 2367
2422 DEFINE_RAW_LEAF_RUNTIME_ENTRY( 2368 DEFINE_RAW_LEAF_RUNTIME_ENTRY(
2423 LibcAtan, 2369 LibcAtan,
2424 1, 2370 1,
2425 true /* is_float */, 2371 true /* is_float */,
2426 reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&atan))); 2372 reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&atan)));
2427 2373
2428 } // namespace dart 2374 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/runtime_entry.h ('k') | runtime/vm/runtime_entry_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698