| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/globals.h" // Needed here to get TARGET_ARCH_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "vm/ast_printer.h" | 10 #include "vm/ast_printer.h" |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 // - A0: object. | 556 // - A0: object. |
| 557 // - A1: instantiator type arguments or raw_null. | 557 // - A1: instantiator type arguments or raw_null. |
| 558 // - A2: instantiator or raw_null. | 558 // - A2: instantiator or raw_null. |
| 559 // Returns: | 559 // Returns: |
| 560 // - true or false in V0. | 560 // - true or false in V0. |
| 561 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos, | 561 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos, |
| 562 intptr_t deopt_id, | 562 intptr_t deopt_id, |
| 563 const AbstractType& type, | 563 const AbstractType& type, |
| 564 bool negate_result, | 564 bool negate_result, |
| 565 LocationSummary* locs) { | 565 LocationSummary* locs) { |
| 566 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 566 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); |
| 567 | 567 |
| 568 // Preserve instantiator (A2) and its type arguments (A1). | 568 // Preserve instantiator (A2) and its type arguments (A1). |
| 569 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 569 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 570 __ sw(A2, Address(SP, 1 * kWordSize)); | 570 __ sw(A2, Address(SP, 1 * kWordSize)); |
| 571 __ sw(A1, Address(SP, 0 * kWordSize)); | 571 __ sw(A1, Address(SP, 0 * kWordSize)); |
| 572 | 572 |
| 573 Label is_instance, is_not_instance; | 573 Label is_instance, is_not_instance; |
| 574 // If type is instantiated and non-parameterized, we can inline code | 574 // If type is instantiated and non-parameterized, we can inline code |
| 575 // checking whether the tested instance is a Smi. | 575 // checking whether the tested instance is a Smi. |
| 576 if (type.IsInstantiated()) { | 576 if (type.IsInstantiated()) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos, | 650 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos, |
| 651 intptr_t deopt_id, | 651 intptr_t deopt_id, |
| 652 const AbstractType& dst_type, | 652 const AbstractType& dst_type, |
| 653 const String& dst_name, | 653 const String& dst_name, |
| 654 LocationSummary* locs) { | 654 LocationSummary* locs) { |
| 655 __ TraceSimMsg("AssertAssignable"); | 655 __ TraceSimMsg("AssertAssignable"); |
| 656 ASSERT(token_pos >= 0); | 656 ASSERT(token_pos >= 0); |
| 657 ASSERT(!dst_type.IsNull()); | 657 ASSERT(!dst_type.IsNull()); |
| 658 ASSERT(dst_type.IsFinalized()); | 658 ASSERT(dst_type.IsFinalized()); |
| 659 // Assignable check is skipped in FlowGraphBuilder, not here. | 659 // Assignable check is skipped in FlowGraphBuilder, not here. |
| 660 ASSERT(dst_type.IsMalformed() || | 660 ASSERT(dst_type.IsMalformed() || dst_type.IsMalbounded() || |
| 661 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); | 661 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); |
| 662 // Preserve instantiator and its type arguments. | 662 // Preserve instantiator and its type arguments. |
| 663 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 663 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 664 __ sw(A2, Address(SP, 1 * kWordSize)); | 664 __ sw(A2, Address(SP, 1 * kWordSize)); |
| 665 | 665 |
| 666 // A null object is always assignable and is returned as result. | 666 // A null object is always assignable and is returned as result. |
| 667 Label is_assignable, runtime_call; | 667 Label is_assignable, runtime_call; |
| 668 | 668 |
| 669 __ BranchEqual(A0, reinterpret_cast<int32_t>(Object::null()), &is_assignable); | 669 __ BranchEqual(A0, reinterpret_cast<int32_t>(Object::null()), &is_assignable); |
| 670 __ delay_slot()->sw(A1, Address(SP, 0 * kWordSize)); | 670 __ delay_slot()->sw(A1, Address(SP, 0 * kWordSize)); |
| 671 | 671 |
| 672 if (!FLAG_eliminate_type_checks || dst_type.IsMalformed()) { | 672 if (!FLAG_eliminate_type_checks || dst_type.IsMalformed()) { |
| 673 // If type checks are not eliminated during the graph building then | 673 // If type checks are not eliminated during the graph building then |
| 674 // a transition sentinel can be seen here. | 674 // a transition sentinel can be seen here. |
| 675 __ BranchEqual(A0, Object::transition_sentinel(), &is_assignable); | 675 __ BranchEqual(A0, Object::transition_sentinel(), &is_assignable); |
| 676 } | 676 } |
| 677 | 677 |
| 678 // Generate throw new TypeError() if the type is malformed. | 678 // Generate throw new TypeError() if the type is malformed or malbounded. |
| 679 if (dst_type.IsMalformed()) { | 679 if (dst_type.IsMalformed() || dst_type.IsMalbounded()) { |
| 680 const Error& error = Error::Handle(dst_type.malformed_error()); | 680 Error& error = Error::Handle(); |
| 681 if (dst_type.IsMalformed()) { |
| 682 error = dst_type.malformed_error(); |
| 683 } else { |
| 684 const bool is_malbounded = dst_type.IsMalboundedWithError(&error); |
| 685 ASSERT(is_malbounded); |
| 686 } |
| 681 const String& error_message = String::ZoneHandle( | 687 const String& error_message = String::ZoneHandle( |
| 682 Symbols::New(error.ToErrorCString())); | 688 Symbols::New(error.ToErrorCString())); |
| 683 | 689 |
| 684 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | 690 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
| 685 __ LoadObject(TMP1, Object::ZoneHandle()); | 691 __ LoadObject(TMP1, Object::ZoneHandle()); |
| 686 __ sw(TMP1, Address(SP, 3 * kWordSize)); // Make room for the result. | 692 __ sw(TMP1, Address(SP, 3 * kWordSize)); // Make room for the result. |
| 687 __ sw(A0, Address(SP, 2 * kWordSize)); // Push the source object. | 693 __ sw(A0, Address(SP, 2 * kWordSize)); // Push the source object. |
| 688 __ LoadObject(TMP1, dst_name); | 694 __ LoadObject(TMP1, dst_name); |
| 689 __ sw(TMP1, Address(SP, 1 * kWordSize)); // Push the destination name. | 695 __ sw(TMP1, Address(SP, 1 * kWordSize)); // Push the destination name. |
| 690 __ LoadObject(TMP1, error_message); | 696 __ LoadObject(TMP1, error_message); |
| (...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1999 __ AddImmediate(SP, kDoubleSize); | 2005 __ AddImmediate(SP, kDoubleSize); |
| 2000 } | 2006 } |
| 2001 | 2007 |
| 2002 | 2008 |
| 2003 #undef __ | 2009 #undef __ |
| 2004 | 2010 |
| 2005 | 2011 |
| 2006 } // namespace dart | 2012 } // namespace dart |
| 2007 | 2013 |
| 2008 #endif // defined TARGET_ARCH_MIPS | 2014 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |