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

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

Issue 10832150: Get rid of ast node ids. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/code_descriptors.cc ('k') | runtime/vm/compiler.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/assembler_macros.h" 7 #include "vm/assembler_macros.h"
8 #include "vm/ast.h" 8 #include "vm/ast.h"
9 #include "vm/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 static intptr_t GetCallerLocation() { 141 static intptr_t GetCallerLocation() {
142 DartFrameIterator iterator; 142 DartFrameIterator iterator;
143 StackFrame* caller_frame = iterator.NextFrame(); 143 StackFrame* caller_frame = iterator.NextFrame();
144 ASSERT(caller_frame != NULL); 144 ASSERT(caller_frame != NULL);
145 const Code& code = Code::Handle(caller_frame->LookupDartCode()); 145 const Code& code = Code::Handle(caller_frame->LookupDartCode());
146 const PcDescriptors& descriptors = 146 const PcDescriptors& descriptors =
147 PcDescriptors::Handle(code.pc_descriptors()); 147 PcDescriptors::Handle(code.pc_descriptors());
148 ASSERT(!descriptors.IsNull()); 148 ASSERT(!descriptors.IsNull());
149 for (int i = 0; i < descriptors.Length(); i++) { 149 for (int i = 0; i < descriptors.Length(); i++) {
150 if (static_cast<uword>(descriptors.PC(i)) == caller_frame->pc()) { 150 if (static_cast<uword>(descriptors.PC(i)) == caller_frame->pc()) {
151 return descriptors.TokenIndex(i); 151 return descriptors.TokenPos(i);
152 } 152 }
153 } 153 }
154 return -1; 154 return -1;
155 } 155 }
156 156
157 157
158 // Allocate a new object of a generic type and check that the instantiated type 158 // Allocate a new object of a generic type and check that the instantiated type
159 // arguments are within the declared bounds or throw a dynamic type error. 159 // arguments are within the declared bounds or throw a dynamic type error.
160 // Arg0: class of the object that needs to be allocated. 160 // Arg0: class of the object that needs to be allocated.
161 // Arg1: type arguments of the object that needs to be allocated. 161 // Arg1: type arguments of the object that needs to be allocated.
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 427
428 428
429 // This updates the type test cache, an array containing 4-value elements 429 // This updates the type test cache, an array containing 4-value elements
430 // (instance class, instance type arguments, instantiator type arguments and 430 // (instance class, instance type arguments, instantiator type arguments and
431 // test_result). It can be applied to classes with type arguments in which 431 // test_result). It can be applied to classes with type arguments in which
432 // case it contains just the result of the class subtype test, not including 432 // case it contains just the result of the class subtype test, not including
433 // the evaluation of type arguments. 433 // the evaluation of type arguments.
434 // This operation is currently very slow (lookup of code is not efficient yet). 434 // This operation is currently very slow (lookup of code is not efficient yet).
435 // 'instantiator' can be null, in which case inst_targ 435 // 'instantiator' can be null, in which case inst_targ
436 static void UpdateTypeTestCache( 436 static void UpdateTypeTestCache(
437 intptr_t node_id,
438 const Instance& instance, 437 const Instance& instance,
439 const AbstractType& type, 438 const AbstractType& type,
440 const Instance& instantiator, 439 const Instance& instantiator,
441 const AbstractTypeArguments& incoming_instantiator_type_arguments, 440 const AbstractTypeArguments& incoming_instantiator_type_arguments,
442 const Bool& result, 441 const Bool& result,
443 const SubtypeTestCache& new_cache) { 442 const SubtypeTestCache& new_cache) {
444 // Since the test is expensive, don't do it unless necessary. 443 // Since the test is expensive, don't do it unless necessary.
445 // The list of disallowed cases will decrease as they are implemented in 444 // The list of disallowed cases will decrease as they are implemented in
446 // inlined assembly. 445 // inlined assembly.
447 if (new_cache.IsNull()) return; 446 if (new_cache.IsNull()) return;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 Class::Handle(test_type.type_class()).id(), 538 Class::Handle(test_type.type_class()).id(),
540 instantiator_type_arguments.raw(), 539 instantiator_type_arguments.raw(),
541 instantiator_type_arguments.ToCString(), 540 instantiator_type_arguments.ToCString(),
542 result.ToCString()); 541 result.ToCString());
543 } 542 }
544 } 543 }
545 544
546 545
547 // Check that the given instance is an instance of the given type. 546 // Check that the given instance is an instance of the given type.
548 // Tested instance may not be null, because the null test is inlined. 547 // Tested instance may not be null, because the null test is inlined.
549 // Arg0: node id of the instanceof node. 548 // Arg0: instance being checked.
550 // Arg1: instance being checked. 549 // Arg1: type.
551 // Arg2: type. 550 // Arg2: instantiator (or null).
552 // Arg3: instantiator (or null). 551 // Arg3: type arguments of the instantiator of the type.
553 // Arg4: type arguments of the instantiator of the type. 552 // Arg4: SubtypeTestCache.
554 // Arg5: SubtypeTestCache.
555 // Return value: true or false, or may throw a type error in checked mode. 553 // Return value: true or false, or may throw a type error in checked mode.
556 DEFINE_RUNTIME_ENTRY(Instanceof, 6) { 554 DEFINE_RUNTIME_ENTRY(Instanceof, 5) {
557 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count()); 555 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count());
558 intptr_t node_id = Smi::CheckedHandle(arguments.At(0)).Value(); 556 const Instance& instance = Instance::CheckedHandle(arguments.At(0));
559 const Instance& instance = Instance::CheckedHandle(arguments.At(1)); 557 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(1));
560 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(2)); 558 const Instance& instantiator = Instance::CheckedHandle(arguments.At(2));
561 const Instance& instantiator = Instance::CheckedHandle(arguments.At(3));
562 const AbstractTypeArguments& instantiator_type_arguments = 559 const AbstractTypeArguments& instantiator_type_arguments =
563 AbstractTypeArguments::CheckedHandle(arguments.At(4)); 560 AbstractTypeArguments::CheckedHandle(arguments.At(3));
564 const SubtypeTestCache& cache = 561 const SubtypeTestCache& cache =
565 SubtypeTestCache::CheckedHandle(arguments.At(5)); 562 SubtypeTestCache::CheckedHandle(arguments.At(4));
566 ASSERT(type.IsFinalized()); 563 ASSERT(type.IsFinalized());
567 Error& malformed_error = Error::Handle(); 564 Error& malformed_error = Error::Handle();
568 const Bool& result = Bool::Handle( 565 const Bool& result = Bool::Handle(
569 instance.IsInstanceOf(type, 566 instance.IsInstanceOf(type,
570 instantiator_type_arguments, 567 instantiator_type_arguments,
571 &malformed_error) ? 568 &malformed_error) ?
572 Bool::True() : Bool::False()); 569 Bool::True() : Bool::False());
573 if (FLAG_trace_type_checks) { 570 if (FLAG_trace_type_checks) {
574 PrintTypeCheck("InstanceOf", 571 PrintTypeCheck("InstanceOf",
575 instance, type, instantiator_type_arguments, result); 572 instance, type, instantiator_type_arguments, result);
576 } 573 }
577 if (!result.value() && !malformed_error.IsNull()) { 574 if (!result.value() && !malformed_error.IsNull()) {
578 // Throw a dynamic type error only if the instanceof test fails. 575 // Throw a dynamic type error only if the instanceof test fails.
579 const intptr_t location = GetCallerLocation(); 576 const intptr_t location = GetCallerLocation();
580 String& malformed_error_message = String::Handle( 577 String& malformed_error_message = String::Handle(
581 String::New(malformed_error.ToErrorCString())); 578 String::New(malformed_error.ToErrorCString()));
582 const String& no_name = String::Handle(Symbols::Empty()); 579 const String& no_name = String::Handle(Symbols::Empty());
583 Exceptions::CreateAndThrowTypeError( 580 Exceptions::CreateAndThrowTypeError(
584 location, no_name, no_name, no_name, malformed_error_message); 581 location, no_name, no_name, no_name, malformed_error_message);
585 UNREACHABLE(); 582 UNREACHABLE();
586 } 583 }
587 UpdateTypeTestCache(node_id, instance, type, instantiator, 584 UpdateTypeTestCache(instance, type, instantiator,
588 instantiator_type_arguments, result, cache); 585 instantiator_type_arguments, result, cache);
589 arguments.SetReturn(result); 586 arguments.SetReturn(result);
590 } 587 }
591 588
592 589
593 // Check that the type of the given instance is a subtype of the given type and 590 // Check that the type of the given instance is a subtype of the given type and
594 // can therefore be assigned. 591 // can therefore be assigned.
595 // Arg0: node-id of the assignment. 592 // Arg0: instance being assigned.
596 // Arg1: instance being assigned. 593 // Arg1: type being assigned to.
597 // Arg2: type being assigned to. 594 // Arg2: instantiator (or null).
598 // Arg3: instantiator (or null). 595 // Arg3: type arguments of the instantiator of the type being assigned to.
599 // Arg4: type arguments of the instantiator of the type being assigned to. 596 // Arg4: name of variable being assigned to.
600 // Arg5: name of variable being assigned to. 597 // Arg5: SubtypeTestCache.
601 // Arg6: SubtypeTestCache.
602 // Return value: instance if a subtype, otherwise throw a TypeError. 598 // Return value: instance if a subtype, otherwise throw a TypeError.
603 DEFINE_RUNTIME_ENTRY(TypeCheck, 7) { 599 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) {
604 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); 600 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count());
605 intptr_t node_id = Smi::CheckedHandle(arguments.At(0)).Value(); 601 const Instance& src_instance = Instance::CheckedHandle(arguments.At(0));
606 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1)); 602 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(1));
607 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(2)); 603 const Instance& dst_instantiator = Instance::CheckedHandle(arguments.At(2));
608 const Instance& dst_instantiator = Instance::CheckedHandle(arguments.At(3));
609 const AbstractTypeArguments& instantiator_type_arguments = 604 const AbstractTypeArguments& instantiator_type_arguments =
610 AbstractTypeArguments::CheckedHandle(arguments.At(4)); 605 AbstractTypeArguments::CheckedHandle(arguments.At(3));
611 const String& dst_name = String::CheckedHandle(arguments.At(5)); 606 const String& dst_name = String::CheckedHandle(arguments.At(4));
612 const SubtypeTestCache& cache = 607 const SubtypeTestCache& cache =
613 SubtypeTestCache::CheckedHandle(arguments.At(6)); 608 SubtypeTestCache::CheckedHandle(arguments.At(5));
614 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. 609 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
615 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. 610 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator.
616 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. 611 ASSERT(!src_instance.IsNull()); // Already checked in inlined code.
617 612
618 Error& malformed_error = Error::Handle(); 613 Error& malformed_error = Error::Handle();
619 const bool is_instance_of = src_instance.IsInstanceOf( 614 const bool is_instance_of = src_instance.IsInstanceOf(
620 dst_type, instantiator_type_arguments, &malformed_error); 615 dst_type, instantiator_type_arguments, &malformed_error);
621 616
622 if (FLAG_trace_type_checks) { 617 if (FLAG_trace_type_checks) {
623 PrintTypeCheck("TypeCheck", 618 PrintTypeCheck("TypeCheck",
(...skipping 16 matching lines...) Expand all
640 } 635 }
641 String& malformed_error_message = String::Handle(); 636 String& malformed_error_message = String::Handle();
642 if (!malformed_error.IsNull()) { 637 if (!malformed_error.IsNull()) {
643 ASSERT(FLAG_enable_type_checks); 638 ASSERT(FLAG_enable_type_checks);
644 malformed_error_message = String::New(malformed_error.ToErrorCString()); 639 malformed_error_message = String::New(malformed_error.ToErrorCString());
645 } 640 }
646 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, 641 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name,
647 dst_name, malformed_error_message); 642 dst_name, malformed_error_message);
648 UNREACHABLE(); 643 UNREACHABLE();
649 } 644 }
650 UpdateTypeTestCache(node_id, src_instance, dst_type, 645 UpdateTypeTestCache(src_instance, dst_type,
651 dst_instantiator, instantiator_type_arguments, 646 dst_instantiator, instantiator_type_arguments,
652 Bool::ZoneHandle(Bool::True()), cache); 647 Bool::ZoneHandle(Bool::True()), cache);
653 arguments.SetReturn(src_instance); 648 arguments.SetReturn(src_instance);
654 } 649 }
655 650
656 651
657 // Report that the type of the given object is not bool in conditional context. 652 // Report that the type of the given object is not bool in conditional context.
658 // Arg0: bad object. 653 // Arg0: bad object.
659 // Return value: none, throws a TypeError. 654 // Return value: none, throws a TypeError.
660 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) { 655 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) {
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 } 1389 }
1395 1390
1396 1391
1397 static intptr_t GetDeoptInfo(const Code& code, uword pc) { 1392 static intptr_t GetDeoptInfo(const Code& code, uword pc) {
1398 const PcDescriptors& descriptors = 1393 const PcDescriptors& descriptors =
1399 PcDescriptors::Handle(code.pc_descriptors()); 1394 PcDescriptors::Handle(code.pc_descriptors());
1400 ASSERT(!descriptors.IsNull()); 1395 ASSERT(!descriptors.IsNull());
1401 // Locate deopt id at deoptimization point inside optimized code. 1396 // Locate deopt id at deoptimization point inside optimized code.
1402 for (int i = 0; i < descriptors.Length(); i++) { 1397 for (int i = 0; i < descriptors.Length(); i++) {
1403 if (static_cast<uword>(descriptors.PC(i)) == pc) { 1398 if (static_cast<uword>(descriptors.PC(i)) == pc) {
1404 return descriptors.NodeId(i); 1399 return descriptors.DeoptId(i);
1405 } 1400 }
1406 } 1401 }
1407 return Computation::kNoCid; 1402 return Isolate::kNoDeoptId;
1408 } 1403 }
1409 1404
1410 1405
1411 // Copy saved registers and caller's frame into temporary buffers. 1406 // Copy saved registers and caller's frame into temporary buffers.
1412 // Access the deopt information for the deoptimization point. 1407 // Access the deopt information for the deoptimization point.
1413 // Return the new stack size (including PC marker and deopt return address, 1408 // Return the new stack size (including PC marker and deopt return address,
1414 // excluding FP). 1409 // excluding FP).
1415 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 1410 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
1416 intptr_t deopt_reason, 1411 intptr_t deopt_reason,
1417 intptr_t* saved_registers_address) { 1412 intptr_t* saved_registers_address) {
(...skipping 13 matching lines...) Expand all
1431 } 1426 }
1432 isolate->set_deopt_registers_copy(registers_copy); 1427 isolate->set_deopt_registers_copy(registers_copy);
1433 ASSERT(reinterpret_cast<uword>(saved_registers_address) == last_fp); 1428 ASSERT(reinterpret_cast<uword>(saved_registers_address) == last_fp);
1434 DartFrameIterator iterator(last_fp); 1429 DartFrameIterator iterator(last_fp);
1435 StackFrame* caller_frame = iterator.NextFrame(); 1430 StackFrame* caller_frame = iterator.NextFrame();
1436 ASSERT(caller_frame != NULL); 1431 ASSERT(caller_frame != NULL);
1437 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); 1432 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
1438 ASSERT(optimized_code.is_optimized()); 1433 ASSERT(optimized_code.is_optimized());
1439 1434
1440 const intptr_t deopt_id = GetDeoptInfo(optimized_code, caller_frame->pc()); 1435 const intptr_t deopt_id = GetDeoptInfo(optimized_code, caller_frame->pc());
1441 ASSERT(deopt_id != Computation::kNoCid); 1436 ASSERT(deopt_id != Isolate::kNoDeoptId);
1442 1437
1443 // Add incoming arguments. 1438 // Add incoming arguments.
1444 const Function& function = Function::Handle(optimized_code.function()); 1439 const Function& function = Function::Handle(optimized_code.function());
1445 // Think of copied arguments. 1440 // Think of copied arguments.
1446 const intptr_t num_args = (function.num_optional_parameters() > 0) ? 1441 const intptr_t num_args = (function.num_optional_parameters() > 0) ?
1447 0 : function.num_fixed_parameters(); 1442 0 : function.num_fixed_parameters();
1448 // FP, PC marker and return address will all be copied. 1443 // FP, PC marker and return address will all be copied.
1449 const intptr_t frame_copy_size = 1444 const intptr_t frame_copy_size =
1450 1 // Deoptimized function's return address: caller_frame->pc(). 1445 1 // Deoptimized function's return address: caller_frame->pc().
1451 + ((caller_frame->fp() - caller_frame->sp()) / kWordSize) 1446 + ((caller_frame->fp() - caller_frame->sp()) / kWordSize)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 const Function& function = Function::Handle(optimized_code.function()); 1486 const Function& function = Function::Handle(optimized_code.function());
1492 ASSERT(!function.IsNull()); 1487 ASSERT(!function.IsNull());
1493 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); 1488 const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
1494 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); 1489 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized());
1495 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); 1490 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized());
1496 1491
1497 intptr_t* frame_copy = isolate->deopt_frame_copy(); 1492 intptr_t* frame_copy = isolate->deopt_frame_copy();
1498 intptr_t* registers_copy = isolate->deopt_registers_copy(); 1493 intptr_t* registers_copy = isolate->deopt_registers_copy();
1499 1494
1500 intptr_t deopt_id = GetDeoptInfo(optimized_code, caller_frame->pc()); 1495 intptr_t deopt_id = GetDeoptInfo(optimized_code, caller_frame->pc());
1501 ASSERT(deopt_id != Computation::kNoCid); 1496 ASSERT(deopt_id != Isolate::kNoDeoptId);
1502 uword continue_at_pc = unoptimized_code.GetDeoptPcAtNodeId(deopt_id); 1497 uword continue_at_pc = unoptimized_code.GetDeoptPcAtDeoptId(deopt_id);
1503 if (FLAG_trace_deopt) { 1498 if (FLAG_trace_deopt) {
1504 OS::Print(" -> continue at 0x%x\n", continue_at_pc); 1499 OS::Print(" -> continue at 0x%x\n", continue_at_pc);
1505 // TODO(srdjan): If we could allow GC, we could print the line where 1500 // TODO(srdjan): If we could allow GC, we could print the line where
1506 // deoptimization occured. 1501 // deoptimization occured.
1507 } 1502 }
1508 const intptr_t deopt_frame_copy_size = isolate->deopt_frame_copy_size(); 1503 const intptr_t deopt_frame_copy_size = isolate->deopt_frame_copy_size();
1509 // TODO(srdjan): Use deopt info to copy the values to right place. 1504 // TODO(srdjan): Use deopt info to copy the values to right place.
1510 const intptr_t pc_marker_index = 1505 const intptr_t pc_marker_index =
1511 ((caller_frame->fp() - caller_frame->sp()) / kWordSize); 1506 ((caller_frame->fp() - caller_frame->sp()) / kWordSize);
1512 // Patch the return PC and saved PC marker in frame to point to the 1507 // Patch the return PC and saved PC marker in frame to point to the
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 } 1611 }
1617 } 1612 }
1618 } 1613 }
1619 // The cache is null terminated, therefore the loop above should never 1614 // The cache is null terminated, therefore the loop above should never
1620 // terminate by itself. 1615 // terminate by itself.
1621 UNREACHABLE(); 1616 UNREACHABLE();
1622 return Code::null(); 1617 return Code::null();
1623 } 1618 }
1624 1619
1625 } // namespace dart 1620 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_descriptors.cc ('k') | runtime/vm/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698