OLD | NEW |
---|---|
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/code_generator.h" | 5 #include "vm/code_generator.h" |
6 | 6 |
7 #include "vm/code_index_table.h" | 7 #include "vm/code_index_table.h" |
8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 arguments.SetReturn(type_arguments); | 221 arguments.SetReturn(type_arguments); |
222 } | 222 } |
223 | 223 |
224 | 224 |
225 // Allocate a new closure. | 225 // Allocate a new closure. |
226 // Arg0: local function. | 226 // Arg0: local function. |
227 // Arg1: type arguments of the closure. | 227 // Arg1: type arguments of the closure. |
228 // Return value: newly allocated closure. | 228 // Return value: newly allocated closure. |
229 DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) { | 229 DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) { |
230 ASSERT(arguments.Count() == kAllocateClosureRuntimeEntry.argument_count()); | 230 ASSERT(arguments.Count() == kAllocateClosureRuntimeEntry.argument_count()); |
231 Isolate* isolate = arguments.isolate(); | |
231 const Function& function = Function::CheckedHandle(arguments.At(0)); | 232 const Function& function = Function::CheckedHandle(arguments.At(0)); |
232 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction()); | 233 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction()); |
233 const TypeArguments& type_arguments = | 234 const TypeArguments& type_arguments = |
234 TypeArguments::CheckedHandle(arguments.At(1)); | 235 TypeArguments::CheckedHandle(arguments.At(1)); |
235 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); | 236 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); |
236 // The current context was saved in the Isolate structure when entering the | 237 // The current context was saved in the Isolate structure when entering the |
237 // runtime. | 238 // runtime. |
238 const Context& context = Context::Handle(Isolate::Current()->top_context()); | 239 const Context& context = Context::Handle(isolate->top_context()); |
239 ASSERT(!context.IsNull()); | 240 ASSERT(!context.IsNull()); |
240 const Closure& closure = Closure::Handle(Closure::New(function, context)); | 241 const Closure& closure = Closure::Handle(Closure::New(function, context)); |
241 closure.SetTypeArguments(type_arguments); | 242 closure.SetTypeArguments(type_arguments); |
242 arguments.SetReturn(closure); | 243 arguments.SetReturn(closure); |
243 } | 244 } |
244 | 245 |
245 | 246 |
246 // Allocate a new implicit static closure. | 247 // Allocate a new implicit static closure. |
247 // Arg0: local function. | 248 // Arg0: local function. |
248 // Return value: newly allocated closure. | 249 // Return value: newly allocated closure. |
249 DEFINE_RUNTIME_ENTRY(AllocateImplicitStaticClosure, 1) { | 250 DEFINE_RUNTIME_ENTRY(AllocateImplicitStaticClosure, 1) { |
250 ASSERT(arguments.Count() == | 251 ASSERT(arguments.Count() == |
251 kAllocateImplicitStaticClosureRuntimeEntry.argument_count()); | 252 kAllocateImplicitStaticClosureRuntimeEntry.argument_count()); |
252 ObjectStore* object_store = Isolate::Current()->object_store(); | 253 Isolate* isolate = arguments.isolate(); |
254 ObjectStore* object_store = isolate->object_store(); | |
253 ASSERT(object_store != NULL); | 255 ASSERT(object_store != NULL); |
254 const Function& function = Function::CheckedHandle(arguments.At(0)); | 256 const Function& function = Function::CheckedHandle(arguments.At(0)); |
255 ASSERT(function.IsImplicitStaticClosureFunction()); | 257 ASSERT(function.IsImplicitStaticClosureFunction()); |
256 const Context& context = Context::Handle(object_store->empty_context()); | 258 const Context& context = Context::Handle(object_store->empty_context()); |
257 arguments.SetReturn(Closure::Handle(Closure::New(function, context))); | 259 arguments.SetReturn(Closure::Handle(Closure::New(function, context))); |
258 } | 260 } |
259 | 261 |
260 | 262 |
261 // Allocate a new implicit instance closure. | 263 // Allocate a new implicit instance closure. |
262 // Arg0: local function. | 264 // Arg0: local function. |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 caller_frame->pc(), | 378 caller_frame->pc(), |
377 target_function.ToFullyQualifiedCString(), | 379 target_function.ToFullyQualifiedCString(), |
378 new_target); | 380 new_target); |
379 } | 381 } |
380 } | 382 } |
381 | 383 |
382 | 384 |
383 // Resolves and compiles the target function of an instance call, updates | 385 // Resolves and compiles the target function of an instance call, updates |
384 // function cache of the receiver's class and returns the compiled code or null. | 386 // function cache of the receiver's class and returns the compiled code or null. |
385 // Only the number of named arguments is checked, but not the actual names. | 387 // Only the number of named arguments is checked, but not the actual names. |
386 static RawCode* ResolveCompileInstanceCallTarget(const Instance& receiver) { | 388 static RawCode* ResolveCompileInstanceCallTarget(Isolate* isolate, |
389 const Instance& receiver) { | |
387 DartFrameIterator iterator; | 390 DartFrameIterator iterator; |
388 DartFrame* caller_frame = iterator.NextFrame(); | 391 DartFrame* caller_frame = iterator.NextFrame(); |
389 ASSERT(caller_frame != NULL); | 392 ASSERT(caller_frame != NULL); |
390 int num_arguments = -1; | 393 int num_arguments = -1; |
391 int num_named_arguments = -1; | 394 int num_named_arguments = -1; |
392 uword target = 0; | 395 uword target = 0; |
393 String& function_name = String::Handle(); | 396 String& function_name = String::Handle(); |
394 CodePatcher::GetInstanceCallAt(caller_frame->pc(), | 397 CodePatcher::GetInstanceCallAt(caller_frame->pc(), |
395 &function_name, | 398 &function_name, |
396 &num_arguments, | 399 &num_arguments, |
397 &num_named_arguments, | 400 &num_named_arguments, |
398 &target); | 401 &target); |
399 ASSERT(function_name.IsSymbol()); | 402 ASSERT(function_name.IsSymbol()); |
400 Class& receiver_class = Class::Handle(); | 403 Class& receiver_class = Class::Handle(); |
401 if (receiver.IsNull()) { | 404 if (receiver.IsNull()) { |
402 // TODO(srdjan): Clarify behavior of null objects. | 405 // TODO(srdjan): Clarify behavior of null objects. |
403 receiver_class = Isolate::Current()->object_store()->object_class(); | 406 receiver_class = isolate->object_store()->object_class(); |
404 } else { | 407 } else { |
405 receiver_class = receiver.clazz(); | 408 receiver_class = receiver.clazz(); |
406 } | 409 } |
407 FunctionsCache functions_cache(receiver_class); | 410 FunctionsCache functions_cache(receiver_class); |
408 Code& code = Code::Handle(); | 411 Code& code = Code::Handle(); |
409 code = functions_cache.LookupCode(function_name, | 412 code = functions_cache.LookupCode(function_name, |
410 num_arguments, | 413 num_arguments, |
411 num_named_arguments); | 414 num_named_arguments); |
412 if (!code.IsNull()) { | 415 if (!code.IsNull()) { |
413 // Function's code found in the cache. | 416 // Function's code found in the cache. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 | 451 |
449 // Resolves an instance function and compiles it if necessary. | 452 // Resolves an instance function and compiles it if necessary. |
450 // Arg0: receiver object. | 453 // Arg0: receiver object. |
451 // Returns: RawCode object or NULL (method not found or not compileable). | 454 // Returns: RawCode object or NULL (method not found or not compileable). |
452 // This is called by the megamorphic stub when instance call does not need to be | 455 // This is called by the megamorphic stub when instance call does not need to be |
453 // patched. | 456 // patched. |
454 // Used by megamorphic lookup/no-such-method-handling. | 457 // Used by megamorphic lookup/no-such-method-handling. |
455 DEFINE_RUNTIME_ENTRY(ResolveCompileInstanceFunction, 1) { | 458 DEFINE_RUNTIME_ENTRY(ResolveCompileInstanceFunction, 1) { |
456 ASSERT(arguments.Count() == | 459 ASSERT(arguments.Count() == |
457 kResolveCompileInstanceFunctionRuntimeEntry.argument_count()); | 460 kResolveCompileInstanceFunctionRuntimeEntry.argument_count()); |
461 Isolate* isolate = arguments.isolate(); | |
458 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 462 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); |
459 const Code& code = Code::Handle(ResolveCompileInstanceCallTarget(receiver)); | 463 const Code& code = Code::Handle( |
464 ResolveCompileInstanceCallTarget(isolate, receiver)); | |
460 arguments.SetReturn(Code::Handle(code.raw())); | 465 arguments.SetReturn(Code::Handle(code.raw())); |
461 } | 466 } |
462 | 467 |
463 | 468 |
464 // Handles inline cache misses by updating the IC data array of the call | 469 // Handles inline cache misses by updating the IC data array of the call |
465 // site. | 470 // site. |
466 // Arg0: Receiver object. | 471 // Arg0: Receiver object. |
467 // Returns: target function with compiled code or 0. | 472 // Returns: target function with compiled code or 0. |
468 // Modifies the instance call to hold the updated IC data array. | 473 // Modifies the instance call to hold the updated IC data array. |
469 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandler, 1) { | 474 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandler, 1) { |
470 ASSERT(arguments.Count() == | 475 ASSERT(arguments.Count() == |
471 kInlineCacheMissHandlerRuntimeEntry.argument_count()); | 476 kInlineCacheMissHandlerRuntimeEntry.argument_count()); |
477 Isolate* isolate = arguments.isolate(); | |
472 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 478 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); |
473 const Code& target_code = | 479 const Code& target_code = |
474 Code::Handle(ResolveCompileInstanceCallTarget(receiver)); | 480 Code::Handle(ResolveCompileInstanceCallTarget(isolate, receiver)); |
475 if (target_code.IsNull()) { | 481 if (target_code.IsNull()) { |
476 // Let the megamorphic stub handle special cases: NoSuchMethod, | 482 // Let the megamorphic stub handle special cases: NoSuchMethod, |
477 // closure calls. | 483 // closure calls. |
478 if (FLAG_trace_ic) { | 484 if (FLAG_trace_ic) { |
479 OS::Print("InlineCacheMissHandler NULL code for receiver: %s\n", | 485 OS::Print("InlineCacheMissHandler NULL code for receiver: %s\n", |
480 receiver.ToCString()); | 486 receiver.ToCString()); |
481 } | 487 } |
482 arguments.SetReturn(target_code); | 488 arguments.SetReturn(target_code); |
483 return; | 489 return; |
484 } | 490 } |
(...skipping 24 matching lines...) Expand all Loading... | |
509 arguments.SetReturn(target_function); | 515 arguments.SetReturn(target_function); |
510 if (FLAG_trace_ic) { | 516 if (FLAG_trace_ic) { |
511 OS::Print("InlineCacheMissHandler call at 0x%x' adding <%s> -> <%s>\n", | 517 OS::Print("InlineCacheMissHandler call at 0x%x' adding <%s> -> <%s>\n", |
512 caller_frame->pc(), | 518 caller_frame->pc(), |
513 Class::Handle(receiver.clazz()).ToCString(), | 519 Class::Handle(receiver.clazz()).ToCString(), |
514 target_function.ToCString()); | 520 target_function.ToCString()); |
515 } | 521 } |
516 } | 522 } |
517 | 523 |
518 | 524 |
519 static RawFunction* LookupDynamicFunction(const Class& in_cls, | 525 static RawFunction* LookupDynamicFunction(Isolate* isolate, |
526 const Class& in_cls, | |
520 const String& name) { | 527 const String& name) { |
521 Class& cls = Class::Handle(); | 528 Class& cls = Class::Handle(); |
522 // For lookups treat null as an instance of class Object. | 529 // For lookups treat null as an instance of class Object. |
523 if (in_cls.IsNullClass()) { | 530 if (in_cls.IsNullClass()) { |
524 cls = Isolate::Current()->object_store()->object_class(); | 531 cls = isolate->object_store()->object_class(); |
525 } else { | 532 } else { |
526 cls = in_cls.raw(); | 533 cls = in_cls.raw(); |
527 } | 534 } |
528 | 535 |
529 Function& function = Function::Handle(); | 536 Function& function = Function::Handle(); |
530 while (!cls.IsNull()) { | 537 while (!cls.IsNull()) { |
531 // Check if function exists. | 538 // Check if function exists. |
532 function = cls.LookupDynamicFunction(name); | 539 function = cls.LookupDynamicFunction(name); |
533 if (!function.IsNull()) { | 540 if (!function.IsNull()) { |
534 break; | 541 break; |
535 } | 542 } |
536 cls = cls.SuperClass(); | 543 cls = cls.SuperClass(); |
537 } | 544 } |
538 return function.raw(); | 545 return function.raw(); |
539 } | 546 } |
540 | 547 |
541 | 548 |
542 // Resolve an implicit closure by checking if an instance function | 549 // Resolve an implicit closure by checking if an instance function |
543 // of the same name exists and creating a closure object of the function. | 550 // of the same name exists and creating a closure object of the function. |
544 // Arg0: receiver object. | 551 // Arg0: receiver object. |
545 // Arg1: ic-data array. | 552 // Arg1: ic-data array. |
546 // Returns: Closure object or NULL (instance function not found). | 553 // Returns: Closure object or NULL (instance function not found). |
547 // This is called by the megamorphic stub when it is unable to resolve an | 554 // This is called by the megamorphic stub when it is unable to resolve an |
548 // instance method. This is done just before the call to noSuchMethod. | 555 // instance method. This is done just before the call to noSuchMethod. |
549 DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureFunction, 2) { | 556 DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureFunction, 2) { |
550 ASSERT(arguments.Count() == | 557 ASSERT(arguments.Count() == |
551 kResolveImplicitClosureFunctionRuntimeEntry.argument_count()); | 558 kResolveImplicitClosureFunctionRuntimeEntry.argument_count()); |
559 Isolate* isolate = arguments.isolate(); | |
552 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 560 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); |
553 const Array& ic_data_array = Array::CheckedHandle(arguments.At(1)); | 561 const Array& ic_data_array = Array::CheckedHandle(arguments.At(1)); |
554 ICData ic_data(ic_data_array); | 562 ICData ic_data(ic_data_array); |
555 const String& original_function_name = String::Handle(ic_data.FunctionName()); | 563 const String& original_function_name = String::Handle(ic_data.FunctionName()); |
556 const String& getter_prefix = String::Handle(String::New("get:")); | 564 const String& getter_prefix = String::Handle(String::New("get:")); |
557 Closure& closure = Closure::Handle(); | 565 Closure& closure = Closure::Handle(); |
558 if (!original_function_name.StartsWith(getter_prefix)) { | 566 if (!original_function_name.StartsWith(getter_prefix)) { |
559 // This is not a getter so can't be the case where we are trying to | 567 // This is not a getter so can't be the case where we are trying to |
560 // create an implicit closure of an instance function. | 568 // create an implicit closure of an instance function. |
561 arguments.SetReturn(closure); | 569 arguments.SetReturn(closure); |
562 return; | 570 return; |
563 } | 571 } |
564 Class& receiver_class = Class::Handle(); | 572 Class& receiver_class = Class::Handle(); |
565 receiver_class ^= receiver.clazz(); | 573 receiver_class ^= receiver.clazz(); |
566 ASSERT(!receiver_class.IsNull()); | 574 ASSERT(!receiver_class.IsNull()); |
567 String& func_name = String::Handle(); | 575 String& func_name = String::Handle(); |
568 func_name = String::SubString(original_function_name, getter_prefix.Length()); | 576 func_name = String::SubString(original_function_name, getter_prefix.Length()); |
569 func_name = String::NewSymbol(func_name); | 577 func_name = String::NewSymbol(func_name); |
570 const Function& function = | 578 const Function& function = Function::Handle( |
571 Function::Handle(LookupDynamicFunction(receiver_class, func_name)); | 579 LookupDynamicFunction(isolate, receiver_class, func_name)); |
572 if (function.IsNull()) { | 580 if (function.IsNull()) { |
573 // There is no function of the same name so can't be the case where | 581 // There is no function of the same name so can't be the case where |
574 // we are trying to create an implicit closure of an instance function. | 582 // we are trying to create an implicit closure of an instance function. |
575 arguments.SetReturn(closure); | 583 arguments.SetReturn(closure); |
576 return; | 584 return; |
577 } | 585 } |
578 Function& implicit_closure_function = | 586 Function& implicit_closure_function = |
579 Function::Handle(function.ImplicitClosureFunction()); | 587 Function::Handle(function.ImplicitClosureFunction()); |
580 // Create a closure object for the implicit closure function. | 588 // Create a closure object for the implicit closure function. |
581 const Context& context = Context::Handle(Context::New(1)); | 589 const Context& context = Context::Handle(Context::New(1)); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
781 ASSERT(arguments.Count() == | 789 ASSERT(arguments.Count() == |
782 kClosureArgumentMismatchRuntimeEntry.argument_count()); | 790 kClosureArgumentMismatchRuntimeEntry.argument_count()); |
783 GrowableArray<const Object*> args; | 791 GrowableArray<const Object*> args; |
784 Exceptions::ThrowByType(Exceptions::kClosureArgumentMismatch, args); | 792 Exceptions::ThrowByType(Exceptions::kClosureArgumentMismatch, args); |
785 } | 793 } |
786 | 794 |
787 | 795 |
788 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { | 796 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { |
789 ASSERT(arguments.Count() == | 797 ASSERT(arguments.Count() == |
790 kStackOverflowRuntimeEntry.argument_count()); | 798 kStackOverflowRuntimeEntry.argument_count()); |
791 uword old_stack_limit = Isolate::Current()->stack_limit(); | 799 Isolate* isolate = arguments.isolate(); |
Ivan Posva
2011/11/11 22:07:07
This is such a repeating pattern that we might con
siva
2011/11/12 03:01:05
Done.
| |
792 Isolate::Current()->AdjustStackLimitForException(); | 800 uword old_stack_limit = isolate->stack_limit(); |
801 isolate->AdjustStackLimitForException(); | |
793 // Recursive stack overflow check. | 802 // Recursive stack overflow check. |
794 ASSERT(old_stack_limit != Isolate::Current()->stack_limit()); | 803 ASSERT(old_stack_limit != isolate->stack_limit()); |
795 GrowableArray<const Object*> args; | 804 GrowableArray<const Object*> args; |
796 Exceptions::ThrowByType(Exceptions::kStackOverflow, args); | 805 Exceptions::ThrowByType(Exceptions::kStackOverflow, args); |
797 Isolate::Current()->ResetStackLimitAfterException(); | 806 isolate->ResetStackLimitAfterException(); |
798 } | 807 } |
799 | 808 |
800 | 809 |
801 // Only unoptimized code has invocation counter threshold checking. | 810 // Only unoptimized code has invocation counter threshold checking. |
802 // Once the invocation counter threshold is reached any entry into the | 811 // Once the invocation counter threshold is reached any entry into the |
803 // unoptimized code is redirected to this function. | 812 // unoptimized code is redirected to this function. |
804 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { | 813 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { |
805 ASSERT(arguments.Count() == | 814 ASSERT(arguments.Count() == |
806 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); | 815 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); |
807 const Function& function = Function::CheckedHandle(arguments.At(0)); | 816 const Function& function = Function::CheckedHandle(arguments.At(0)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
859 | 868 |
860 | 869 |
861 // The top Dart frame belongs to the optimized method that needs to be | 870 // The top Dart frame belongs to the optimized method that needs to be |
862 // deoptimized. The pc of the Dart frame points to the deoptimization point. | 871 // deoptimized. The pc of the Dart frame points to the deoptimization point. |
863 // Find the node id of the deoptimization point and find the continuation | 872 // Find the node id of the deoptimization point and find the continuation |
864 // pc in the unoptimized code. | 873 // pc in the unoptimized code. |
865 // Since both unoptimized and optimized code have the same layout, we need only | 874 // Since both unoptimized and optimized code have the same layout, we need only |
866 // to patch the pc of the Dart frame and to disable/enable appropriate code. | 875 // to patch the pc of the Dart frame and to disable/enable appropriate code. |
867 DEFINE_RUNTIME_ENTRY(Deoptimize, 0) { | 876 DEFINE_RUNTIME_ENTRY(Deoptimize, 0) { |
868 ASSERT(arguments.Count() == kDeoptimizeRuntimeEntry.argument_count()); | 877 ASSERT(arguments.Count() == kDeoptimizeRuntimeEntry.argument_count()); |
878 Isolate* isolate = arguments.isolate(); | |
869 DartFrameIterator iterator; | 879 DartFrameIterator iterator; |
870 DartFrame* caller_frame = iterator.NextFrame(); | 880 DartFrame* caller_frame = iterator.NextFrame(); |
871 ASSERT(caller_frame != NULL); | 881 ASSERT(caller_frame != NULL); |
872 CodeIndexTable* ci_table = Isolate::Current()->code_index_table(); | 882 CodeIndexTable* ci_table = isolate->code_index_table(); |
873 const Code& optimized_code = | 883 const Code& optimized_code = |
874 Code::Handle(ci_table->LookupCode(caller_frame->pc())); | 884 Code::Handle(ci_table->LookupCode(caller_frame->pc())); |
875 const Function& function = Function::Handle(optimized_code.function()); | 885 const Function& function = Function::Handle(optimized_code.function()); |
876 ASSERT(!function.IsNull()); | 886 ASSERT(!function.IsNull()); |
877 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); | 887 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); |
878 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); | 888 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); |
879 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); | 889 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); |
880 const PcDescriptors& descriptors = | 890 const PcDescriptors& descriptors = |
881 PcDescriptors::Handle(optimized_code.pc_descriptors()); | 891 PcDescriptors::Handle(optimized_code.pc_descriptors()); |
882 ASSERT(!descriptors.IsNull()); | 892 ASSERT(!descriptors.IsNull()); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
993 } | 1003 } |
994 } | 1004 } |
995 } | 1005 } |
996 // The cache is null terminated, therefore the loop above should never | 1006 // The cache is null terminated, therefore the loop above should never |
997 // terminate by itself. | 1007 // terminate by itself. |
998 UNREACHABLE(); | 1008 UNREACHABLE(); |
999 return Code::null(); | 1009 return Code::null(); |
1000 } | 1010 } |
1001 | 1011 |
1002 } // namespace dart | 1012 } // namespace dart |
OLD | NEW |