Chromium Code Reviews| 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 |