| OLD | NEW |
| 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/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 locs->set_temp(0, Location::RegisterLocation(RBX)); | 326 locs->set_temp(0, Location::RegisterLocation(RBX)); |
| 327 locs->set_out(Location::RegisterLocation(RAX)); | 327 locs->set_out(Location::RegisterLocation(RAX)); |
| 328 return locs; | 328 return locs; |
| 329 } | 329 } |
| 330 | 330 |
| 331 | 331 |
| 332 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, | 332 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, |
| 333 intptr_t deopt_id, | 333 intptr_t deopt_id, |
| 334 intptr_t token_pos, | 334 intptr_t token_pos, |
| 335 Token::Kind kind, | 335 Token::Kind kind, |
| 336 LocationSummary* locs) { | 336 LocationSummary* locs, |
| 337 const ICData& original_ic_data) { |
| 337 if (!compiler->is_optimizing()) { | 338 if (!compiler->is_optimizing()) { |
| 338 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, | 339 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, |
| 339 deopt_id, | 340 deopt_id, |
| 340 token_pos); | 341 token_pos); |
| 341 } | 342 } |
| 342 const String& operator_name = String::ZoneHandle(Symbols::EqualOperator()); | 343 const String& operator_name = String::ZoneHandle(Symbols::EqualOperator()); |
| 343 const int kNumberOfArguments = 2; | 344 const int kNumberOfArguments = 2; |
| 344 const Array& kNoArgumentNames = Array::Handle(); | 345 const Array& kNoArgumentNames = Array::Handle(); |
| 345 const int kNumArgumentsChecked = 2; | 346 const int kNumArgumentsChecked = 2; |
| 346 | 347 |
| 347 const Immediate raw_null = | 348 const Immediate raw_null = |
| 348 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 349 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 349 Label check_identity; | 350 Label check_identity; |
| 350 __ cmpq(Address(RSP, 0 * kWordSize), raw_null); | 351 __ cmpq(Address(RSP, 0 * kWordSize), raw_null); |
| 351 __ j(EQUAL, &check_identity, Assembler::kNearJump); | 352 __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| 352 __ cmpq(Address(RSP, 1 * kWordSize), raw_null); | 353 __ cmpq(Address(RSP, 1 * kWordSize), raw_null); |
| 353 __ j(EQUAL, &check_identity, Assembler::kNearJump); | 354 __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| 354 const ICData& ic_data = compiler->GenerateInstanceCall(deopt_id, | 355 |
| 355 token_pos, | 356 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw()); |
| 356 operator_name, | 357 if (equality_ic_data.IsNull()) { |
| 357 kNumberOfArguments, | 358 equality_ic_data = ICData::New(compiler->parsed_function().function(), |
| 358 kNoArgumentNames, | 359 operator_name, |
| 359 kNumArgumentsChecked, | 360 deopt_id, |
| 360 locs); | 361 kNumArgumentsChecked); |
| 362 } |
| 363 compiler->GenerateInstanceCall(deopt_id, |
| 364 token_pos, |
| 365 kNumberOfArguments, |
| 366 kNoArgumentNames, |
| 367 locs, |
| 368 equality_ic_data); |
| 361 Label check_ne; | 369 Label check_ne; |
| 362 __ jmp(&check_ne); | 370 __ jmp(&check_ne); |
| 363 | 371 |
| 364 __ Bind(&check_identity); | 372 __ Bind(&check_identity); |
| 365 // Call stub, load IC data in register. The stub will update ICData if | 373 // Call stub, load IC data in register. The stub will update ICData if |
| 366 // necessary. | 374 // necessary. |
| 367 Register ic_data_reg = locs->temp(0).reg(); | 375 Register ic_data_reg = locs->temp(0).reg(); |
| 368 ASSERT(ic_data_reg == RBX); // Stub depends on it. | 376 ASSERT(ic_data_reg == RBX); // Stub depends on it. |
| 369 __ LoadObject(ic_data_reg, ic_data); | 377 __ LoadObject(ic_data_reg, equality_ic_data); |
| 370 compiler->GenerateCall(token_pos, | 378 compiler->GenerateCall(token_pos, |
| 371 &StubCode::EqualityWithNullArgLabel(), | 379 &StubCode::EqualityWithNullArgLabel(), |
| 372 PcDescriptors::kOther, | 380 PcDescriptors::kOther, |
| 373 locs); | 381 locs); |
| 374 __ Drop(2); | 382 __ Drop(2); |
| 375 __ Bind(&check_ne); | 383 __ Bind(&check_ne); |
| 376 if (kind == Token::kNE) { | 384 if (kind == Token::kNE) { |
| 377 Label false_label, true_label, done; | 385 Label false_label, true_label, done; |
| 378 // Negate the condition: true label returns false and vice versa. | 386 // Negate the condition: true label returns false and vice versa. |
| 379 __ CompareObject(RAX, compiler->bool_true()); | 387 __ CompareObject(RAX, compiler->bool_true()); |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 return; | 706 return; |
| 699 } | 707 } |
| 700 Register left = locs()->in(0).reg(); | 708 Register left = locs()->in(0).reg(); |
| 701 Register right = locs()->in(1).reg(); | 709 Register right = locs()->in(1).reg(); |
| 702 __ pushq(left); | 710 __ pushq(left); |
| 703 __ pushq(right); | 711 __ pushq(right); |
| 704 EmitEqualityAsInstanceCall(compiler, | 712 EmitEqualityAsInstanceCall(compiler, |
| 705 deopt_id(), | 713 deopt_id(), |
| 706 token_pos(), | 714 token_pos(), |
| 707 kind(), | 715 kind(), |
| 708 locs()); | 716 locs(), |
| 717 *ic_data()); |
| 709 ASSERT(locs()->out().reg() == RAX); | 718 ASSERT(locs()->out().reg() == RAX); |
| 710 } | 719 } |
| 711 | 720 |
| 712 | 721 |
| 713 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 722 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 714 BranchInstr* branch) { | 723 BranchInstr* branch) { |
| 715 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 724 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 716 if (receiver_class_id() == kSmiCid) { | 725 if (receiver_class_id() == kSmiCid) { |
| 717 // Deoptimizes if both arguments not Smi. | 726 // Deoptimizes if both arguments not Smi. |
| 718 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 727 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 736 return; | 745 return; |
| 737 } | 746 } |
| 738 Register left = locs()->in(0).reg(); | 747 Register left = locs()->in(0).reg(); |
| 739 Register right = locs()->in(1).reg(); | 748 Register right = locs()->in(1).reg(); |
| 740 __ pushq(left); | 749 __ pushq(left); |
| 741 __ pushq(right); | 750 __ pushq(right); |
| 742 EmitEqualityAsInstanceCall(compiler, | 751 EmitEqualityAsInstanceCall(compiler, |
| 743 deopt_id(), | 752 deopt_id(), |
| 744 token_pos(), | 753 token_pos(), |
| 745 Token::kEQ, // kNE reverse occurs at branch. | 754 Token::kEQ, // kNE reverse occurs at branch. |
| 746 locs()); | 755 locs(), |
| 756 *ic_data()); |
| 747 if (branch->is_checked()) { | 757 if (branch->is_checked()) { |
| 748 EmitAssertBoolean(RAX, token_pos(), locs(), compiler); | 758 EmitAssertBoolean(RAX, token_pos(), locs(), compiler); |
| 749 } | 759 } |
| 750 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; | 760 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; |
| 751 __ CompareObject(RAX, compiler->bool_true()); | 761 __ CompareObject(RAX, compiler->bool_true()); |
| 752 branch->EmitBranchOnCondition(compiler, branch_condition); | 762 branch->EmitBranchOnCondition(compiler, branch_condition); |
| 753 } | 763 } |
| 754 | 764 |
| 755 | 765 |
| 756 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 766 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 } | 833 } |
| 824 const String& function_name = | 834 const String& function_name = |
| 825 String::ZoneHandle(Symbols::New(Token::Str(kind()))); | 835 String::ZoneHandle(Symbols::New(Token::Str(kind()))); |
| 826 if (!compiler->is_optimizing()) { | 836 if (!compiler->is_optimizing()) { |
| 827 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, | 837 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, |
| 828 deopt_id(), | 838 deopt_id(), |
| 829 token_pos()); | 839 token_pos()); |
| 830 } | 840 } |
| 831 const intptr_t kNumArguments = 2; | 841 const intptr_t kNumArguments = 2; |
| 832 const intptr_t kNumArgsChecked = 2; // Type-feedback. | 842 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 843 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); |
| 844 if (relational_ic_data.IsNull()) { |
| 845 relational_ic_data = ICData::New(compiler->parsed_function().function(), |
| 846 function_name, |
| 847 deopt_id(), |
| 848 kNumArgsChecked); |
| 849 } |
| 833 compiler->GenerateInstanceCall(deopt_id(), | 850 compiler->GenerateInstanceCall(deopt_id(), |
| 834 token_pos(), | 851 token_pos(), |
| 835 function_name, | |
| 836 kNumArguments, | 852 kNumArguments, |
| 837 Array::ZoneHandle(), // No optional arguments. | 853 Array::ZoneHandle(), // No optional arguments. |
| 838 kNumArgsChecked, | 854 locs(), |
| 839 locs()); | 855 relational_ic_data); |
| 840 } | 856 } |
| 841 | 857 |
| 842 | 858 |
| 843 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 859 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 844 BranchInstr* branch) { | 860 BranchInstr* branch) { |
| 845 if (operands_class_id() == kSmiCid) { | 861 if (operands_class_id() == kSmiCid) { |
| 846 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 862 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 847 return; | 863 return; |
| 848 } | 864 } |
| 849 if (operands_class_id() == kDoubleCid) { | 865 if (operands_class_id() == kDoubleCid) { |
| (...skipping 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2283 | 2299 |
| 2284 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2300 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2285 UNIMPLEMENTED(); | 2301 UNIMPLEMENTED(); |
| 2286 } | 2302 } |
| 2287 | 2303 |
| 2288 } // namespace dart | 2304 } // namespace dart |
| 2289 | 2305 |
| 2290 #undef __ | 2306 #undef __ |
| 2291 | 2307 |
| 2292 #endif // defined TARGET_ARCH_X64 | 2308 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |