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

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

Issue 8528010: Changes to pass the current isolate to all runtime and native calls. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 1 month 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 | Annotate | Revision Log
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/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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698