| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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" |
| 11 #include "vm/flow_graph_compiler.h" | 11 #include "vm/flow_graph_compiler.h" |
| 12 #include "vm/locations.h" | 12 #include "vm/locations.h" |
| 13 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
| 14 #include "vm/parser.h" | 14 #include "vm/parser.h" |
| 15 #include "vm/stub_code.h" | 15 #include "vm/stub_code.h" |
| 16 #include "vm/symbols.h" | 16 #include "vm/symbols.h" |
| 17 | 17 |
| 18 #define __ compiler->assembler()-> | 18 #define __ compiler->assembler()-> |
| 19 | 19 |
| 20 namespace dart { | 20 namespace dart { |
| 21 | 21 |
| 22 DECLARE_FLAG(int, optimization_counter_threshold); | 22 DECLARE_FLAG(int, optimization_counter_threshold); |
| 23 DECLARE_FLAG(bool, trace_functions); | 23 DECLARE_FLAG(bool, trace_functions); |
| 24 | 24 |
| 25 // Generic summary for call instructions that have all arguments pushed | 25 // Generic summary for call instructions that have all arguments pushed |
| 26 // on the stack and return the result in a fixed register EAX. | 26 // on the stack and return the result in a fixed register EAX. |
| 27 LocationSummary* Instruction::MakeCallSummary() { | 27 LocationSummary* Computation::MakeCallSummary() { |
| 28 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); | 28 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
| 29 result->set_out(Location::RegisterLocation(EAX)); | 29 result->set_out(Location::RegisterLocation(EAX)); |
| 30 return result; | 30 return result; |
| 31 } | 31 } |
| 32 | 32 |
| 33 | 33 |
| 34 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 35 computation()->EmitNativeCode(compiler); |
| 36 if (is_used() && !compiler->is_optimizing()) { |
| 37 __ pushl(locs()->out().reg()); |
| 38 } |
| 39 } |
| 40 |
| 41 |
| 34 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 42 LocationSummary* ReturnInstr::MakeLocationSummary() const { |
| 35 const intptr_t kNumInputs = 1; | 43 const intptr_t kNumInputs = 1; |
| 36 const intptr_t kNumTemps = 1; | 44 const intptr_t kNumTemps = 1; |
| 37 LocationSummary* locs = | 45 LocationSummary* locs = |
| 38 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 46 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 39 locs->set_in(0, Location::RegisterLocation(EAX)); | 47 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 40 locs->set_temp(0, Location::RequiresRegister()); | 48 locs->set_temp(0, Location::RequiresRegister()); |
| 41 return locs; | 49 return locs; |
| 42 } | 50 } |
| 43 | 51 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 | 111 |
| 104 // Generate 1 byte NOP so that the debugger can patch the | 112 // Generate 1 byte NOP so that the debugger can patch the |
| 105 // return pattern with a call to the debug stub. | 113 // return pattern with a call to the debug stub. |
| 106 __ nop(1); | 114 __ nop(1); |
| 107 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, | 115 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
| 108 deopt_id(), | 116 deopt_id(), |
| 109 token_pos()); | 117 token_pos()); |
| 110 } | 118 } |
| 111 | 119 |
| 112 | 120 |
| 113 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { | 121 LocationSummary* ClosureCallComp::MakeLocationSummary() const { |
| 114 const intptr_t kNumInputs = 0; | 122 const intptr_t kNumInputs = 0; |
| 115 const intptr_t kNumTemps = 1; | 123 const intptr_t kNumTemps = 1; |
| 116 LocationSummary* result = | 124 LocationSummary* result = |
| 117 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 125 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 118 result->set_out(Location::RegisterLocation(EAX)); | 126 result->set_out(Location::RegisterLocation(EAX)); |
| 119 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor. | 127 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor. |
| 120 return result; | 128 return result; |
| 121 } | 129 } |
| 122 | 130 |
| 123 | 131 |
| 124 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { | 132 LocationSummary* LoadLocalComp::MakeLocationSummary() const { |
| 125 return LocationSummary::Make(0, | 133 return LocationSummary::Make(0, |
| 126 Location::RequiresRegister(), | 134 Location::RequiresRegister(), |
| 127 LocationSummary::kNoCall); | 135 LocationSummary::kNoCall); |
| 128 } | 136 } |
| 129 | 137 |
| 130 | 138 |
| 131 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 139 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 132 Register result = locs()->out().reg(); | 140 Register result = locs()->out().reg(); |
| 133 __ movl(result, Address(EBP, local().index() * kWordSize)); | 141 __ movl(result, Address(EBP, local().index() * kWordSize)); |
| 134 } | 142 } |
| 135 | 143 |
| 136 | 144 |
| 137 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { | 145 LocationSummary* StoreLocalComp::MakeLocationSummary() const { |
| 138 return LocationSummary::Make(1, | 146 return LocationSummary::Make(1, |
| 139 Location::SameAsFirstInput(), | 147 Location::SameAsFirstInput(), |
| 140 LocationSummary::kNoCall); | 148 LocationSummary::kNoCall); |
| 141 } | 149 } |
| 142 | 150 |
| 143 | 151 |
| 144 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 152 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 145 Register value = locs()->in(0).reg(); | 153 Register value = locs()->in(0).reg(); |
| 146 Register result = locs()->out().reg(); | 154 Register result = locs()->out().reg(); |
| 147 ASSERT(result == value); // Assert that register assignment is correct. | 155 ASSERT(result == value); // Assert that register assignment is correct. |
| 148 __ movl(Address(EBP, local().index() * kWordSize), value); | 156 __ movl(Address(EBP, local().index() * kWordSize), value); |
| 149 } | 157 } |
| 150 | 158 |
| 151 | 159 |
| 152 LocationSummary* ConstantInstr::MakeLocationSummary() const { | 160 LocationSummary* ConstantComp::MakeLocationSummary() const { |
| 153 return LocationSummary::Make(0, | 161 return LocationSummary::Make(0, |
| 154 Location::RequiresRegister(), | 162 Location::RequiresRegister(), |
| 155 LocationSummary::kNoCall); | 163 LocationSummary::kNoCall); |
| 156 } | 164 } |
| 157 | 165 |
| 158 | 166 |
| 159 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 167 void ConstantComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 160 // The register allocator drops constant definitions that have no uses. | 168 // Register allocator drops constant definitions that have no uses. |
| 161 if (!locs()->out().IsInvalid()) { | 169 if (!locs()->out().IsInvalid()) { |
| 162 Register result = locs()->out().reg(); | 170 Register result = locs()->out().reg(); |
| 163 __ LoadObject(result, value()); | 171 __ LoadObject(result, value()); |
| 164 } | 172 } |
| 165 } | 173 } |
| 166 | 174 |
| 167 | 175 |
| 168 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { | 176 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { |
| 169 const intptr_t kNumInputs = 3; | 177 const intptr_t kNumInputs = 3; |
| 170 const intptr_t kNumTemps = 0; | 178 const intptr_t kNumTemps = 0; |
| 171 LocationSummary* summary = | 179 LocationSummary* summary = |
| 172 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 180 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 173 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. | 181 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. |
| 174 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. | 182 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. |
| 175 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments. | 183 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments. |
| 176 summary->set_out(Location::RegisterLocation(EAX)); | 184 summary->set_out(Location::RegisterLocation(EAX)); |
| 177 return summary; | 185 return summary; |
| 178 } | 186 } |
| 179 | 187 |
| 180 | 188 |
| 181 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { | 189 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { |
| 182 const intptr_t kNumInputs = 1; | 190 const intptr_t kNumInputs = 1; |
| 183 const intptr_t kNumTemps = 0; | 191 const intptr_t kNumTemps = 0; |
| 184 LocationSummary* locs = | 192 LocationSummary* locs = |
| 185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 193 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 186 locs->set_in(0, Location::RegisterLocation(EAX)); | 194 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 187 locs->set_out(Location::RegisterLocation(EAX)); | 195 locs->set_out(Location::RegisterLocation(EAX)); |
| 188 return locs; | 196 return locs; |
| 189 } | 197 } |
| 190 | 198 |
| 191 | 199 |
| 192 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 200 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 193 Register obj = locs()->in(0).reg(); | 201 Register obj = locs()->in(0).reg(); |
| 194 Register result = locs()->out().reg(); | 202 Register result = locs()->out().reg(); |
| 195 | 203 |
| 196 if (!is_eliminated()) { | 204 if (!is_eliminated()) { |
| 197 // Check that the type of the value is allowed in conditional context. | 205 // Check that the type of the value is allowed in conditional context. |
| 198 // Call the runtime if the object is not bool::true or bool::false. | 206 // Call the runtime if the object is not bool::true or bool::false. |
| 199 Label done; | 207 Label done; |
| 200 __ CompareObject(obj, compiler->bool_true()); | 208 __ CompareObject(obj, compiler->bool_true()); |
| 201 __ j(EQUAL, &done, Assembler::kNearJump); | 209 __ j(EQUAL, &done, Assembler::kNearJump); |
| 202 __ CompareObject(obj, compiler->bool_false()); | 210 __ CompareObject(obj, compiler->bool_false()); |
| 203 __ j(EQUAL, &done, Assembler::kNearJump); | 211 __ j(EQUAL, &done, Assembler::kNearJump); |
| 204 | 212 |
| 205 __ pushl(obj); // Push the source object. | 213 __ pushl(obj); // Push the source object. |
| 206 compiler->GenerateCallRuntime(token_pos(), | 214 compiler->GenerateCallRuntime(token_pos(), |
| 207 kConditionTypeErrorRuntimeEntry, | 215 kConditionTypeErrorRuntimeEntry, |
| 208 locs()); | 216 locs()); |
| 209 // We should never return here. | 217 // We should never return here. |
| 210 __ int3(); | 218 __ int3(); |
| 211 __ Bind(&done); | 219 __ Bind(&done); |
| 212 } | 220 } |
| 213 ASSERT(obj == result); | 221 ASSERT(obj == result); |
| 214 } | 222 } |
| 215 | 223 |
| 216 | 224 |
| 217 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const { | 225 LocationSummary* ArgumentDefinitionTestComp::MakeLocationSummary() const { |
| 218 const intptr_t kNumInputs = 1; | 226 const intptr_t kNumInputs = 1; |
| 219 const intptr_t kNumTemps = 0; | 227 const intptr_t kNumTemps = 0; |
| 220 LocationSummary* locs = | 228 LocationSummary* locs = |
| 221 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 229 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 222 locs->set_in(0, Location::RegisterLocation(EAX)); | 230 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 223 locs->set_out(Location::RegisterLocation(EAX)); | 231 locs->set_out(Location::RegisterLocation(EAX)); |
| 224 return locs; | 232 return locs; |
| 225 } | 233 } |
| 226 | 234 |
| 227 | 235 |
| 228 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 236 void ArgumentDefinitionTestComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 229 Register saved_args_desc = locs()->in(0).reg(); | 237 Register saved_args_desc = locs()->in(0).reg(); |
| 230 Register result = locs()->out().reg(); | 238 Register result = locs()->out().reg(); |
| 231 | 239 |
| 232 // Push the result place holder initialized to NULL. | 240 // Push the result place holder initialized to NULL. |
| 233 __ PushObject(Object::ZoneHandle()); | 241 __ PushObject(Object::ZoneHandle()); |
| 234 __ pushl(Immediate(Smi::RawValue(formal_parameter_index()))); | 242 __ pushl(Immediate(Smi::RawValue(formal_parameter_index()))); |
| 235 __ PushObject(formal_parameter_name()); | 243 __ PushObject(formal_parameter_name()); |
| 236 __ pushl(saved_args_desc); | 244 __ pushl(saved_args_desc); |
| 237 compiler->GenerateCallRuntime(token_pos(), | 245 compiler->GenerateCallRuntime(token_pos(), |
| 238 kArgumentDefinitionTestRuntimeEntry, | 246 kArgumentDefinitionTestRuntimeEntry, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 250 case Token::kGT: return GREATER; | 258 case Token::kGT: return GREATER; |
| 251 case Token::kLTE: return LESS_EQUAL; | 259 case Token::kLTE: return LESS_EQUAL; |
| 252 case Token::kGTE: return GREATER_EQUAL; | 260 case Token::kGTE: return GREATER_EQUAL; |
| 253 default: | 261 default: |
| 254 UNREACHABLE(); | 262 UNREACHABLE(); |
| 255 return OVERFLOW; | 263 return OVERFLOW; |
| 256 } | 264 } |
| 257 } | 265 } |
| 258 | 266 |
| 259 | 267 |
| 260 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { | 268 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
| 261 const intptr_t kNumInputs = 2; | 269 const intptr_t kNumInputs = 2; |
| 262 const bool is_checked_strict_equal = | 270 const bool is_checked_strict_equal = |
| 263 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); | 271 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); |
| 264 if (receiver_class_id() == kDoubleCid) { | 272 if (receiver_class_id() == kDoubleCid) { |
| 265 const intptr_t kNumTemps = 0; | 273 const intptr_t kNumTemps = 0; |
| 266 LocationSummary* locs = | 274 LocationSummary* locs = |
| 267 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 275 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 268 locs->set_in(0, Location::RequiresXmmRegister()); | 276 locs->set_in(0, Location::RequiresXmmRegister()); |
| 269 locs->set_in(1, Location::RequiresXmmRegister()); | 277 locs->set_in(1, Location::RequiresXmmRegister()); |
| 270 locs->set_out(Location::RequiresRegister()); | 278 locs->set_out(Location::RequiresRegister()); |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 if (branch != NULL) { | 610 if (branch != NULL) { |
| 603 compiler->EmitDoubleCompareBranch( | 611 compiler->EmitDoubleCompareBranch( |
| 604 true_condition, left, right, branch); | 612 true_condition, left, right, branch); |
| 605 } else { | 613 } else { |
| 606 compiler->EmitDoubleCompareBool( | 614 compiler->EmitDoubleCompareBool( |
| 607 true_condition, left, right, locs.out().reg()); | 615 true_condition, left, right, locs.out().reg()); |
| 608 } | 616 } |
| 609 } | 617 } |
| 610 | 618 |
| 611 | 619 |
| 612 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 620 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 613 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 621 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 614 BranchInstr* kNoBranch = NULL; | 622 BranchInstr* kNoBranch = NULL; |
| 615 if (receiver_class_id() == kSmiCid) { | 623 if (receiver_class_id() == kSmiCid) { |
| 616 // Deoptimizes if both arguments not Smi. | 624 // Deoptimizes if both arguments not Smi. |
| 617 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); | 625 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| 618 return; | 626 return; |
| 619 } | 627 } |
| 620 if (receiver_class_id() == kDoubleCid) { | 628 if (receiver_class_id() == kDoubleCid) { |
| 621 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); | 629 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| 622 return; | 630 return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 635 } | 643 } |
| 636 Register left = locs()->in(0).reg(); | 644 Register left = locs()->in(0).reg(); |
| 637 Register right = locs()->in(1).reg(); | 645 Register right = locs()->in(1).reg(); |
| 638 __ pushl(left); | 646 __ pushl(left); |
| 639 __ pushl(right); | 647 __ pushl(right); |
| 640 EmitEqualityAsInstanceCall(compiler, deopt_id(), token_pos(), kind(), locs()); | 648 EmitEqualityAsInstanceCall(compiler, deopt_id(), token_pos(), kind(), locs()); |
| 641 ASSERT(locs()->out().reg() == EAX); | 649 ASSERT(locs()->out().reg() == EAX); |
| 642 } | 650 } |
| 643 | 651 |
| 644 | 652 |
| 645 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 653 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler, |
| 646 BranchInstr* branch) { | 654 BranchInstr* branch) { |
| 647 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 655 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 648 if (receiver_class_id() == kSmiCid) { | 656 if (receiver_class_id() == kSmiCid) { |
| 649 // Deoptimizes if both arguments not Smi. | 657 // Deoptimizes if both arguments not Smi. |
| 650 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 658 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 651 return; | 659 return; |
| 652 } | 660 } |
| 653 if (receiver_class_id() == kDoubleCid) { | 661 if (receiver_class_id() == kDoubleCid) { |
| 654 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 662 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 655 return; | 663 return; |
| 656 } | 664 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 674 deopt_id(), | 682 deopt_id(), |
| 675 token_pos(), | 683 token_pos(), |
| 676 Token::kEQ, // kNE reverse occurs at branch. | 684 Token::kEQ, // kNE reverse occurs at branch. |
| 677 locs()); | 685 locs()); |
| 678 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; | 686 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; |
| 679 __ CompareObject(EAX, compiler->bool_true()); | 687 __ CompareObject(EAX, compiler->bool_true()); |
| 680 branch->EmitBranchOnCondition(compiler, branch_condition); | 688 branch->EmitBranchOnCondition(compiler, branch_condition); |
| 681 } | 689 } |
| 682 | 690 |
| 683 | 691 |
| 684 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 692 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| 685 const intptr_t kNumInputs = 2; | 693 const intptr_t kNumInputs = 2; |
| 686 if (operands_class_id() == kDoubleCid) { | 694 if (operands_class_id() == kDoubleCid) { |
| 687 const intptr_t kNumTemps = 0; | 695 const intptr_t kNumTemps = 0; |
| 688 LocationSummary* summary = | 696 LocationSummary* summary = |
| 689 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 697 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 690 summary->set_in(0, Location::RequiresXmmRegister()); | 698 summary->set_in(0, Location::RequiresXmmRegister()); |
| 691 summary->set_in(1, Location::RequiresXmmRegister()); | 699 summary->set_in(1, Location::RequiresXmmRegister()); |
| 692 summary->set_out(Location::RequiresRegister()); | 700 summary->set_out(Location::RequiresRegister()); |
| 693 return summary; | 701 return summary; |
| 694 } else if (operands_class_id() == kSmiCid) { | 702 } else if (operands_class_id() == kSmiCid) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 705 LocationSummary* locs = | 713 LocationSummary* locs = |
| 706 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 714 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 707 // Pick arbitrary fixed input registers because this is a call. | 715 // Pick arbitrary fixed input registers because this is a call. |
| 708 locs->set_in(0, Location::RegisterLocation(EAX)); | 716 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 709 locs->set_in(1, Location::RegisterLocation(ECX)); | 717 locs->set_in(1, Location::RegisterLocation(ECX)); |
| 710 locs->set_out(Location::RegisterLocation(EAX)); | 718 locs->set_out(Location::RegisterLocation(EAX)); |
| 711 return locs; | 719 return locs; |
| 712 } | 720 } |
| 713 | 721 |
| 714 | 722 |
| 715 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 723 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 716 if (operands_class_id() == kSmiCid) { | 724 if (operands_class_id() == kSmiCid) { |
| 717 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); | 725 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); |
| 718 return; | 726 return; |
| 719 } | 727 } |
| 720 if (operands_class_id() == kDoubleCid) { | 728 if (operands_class_id() == kDoubleCid) { |
| 721 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); | 729 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); |
| 722 return; | 730 return; |
| 723 } | 731 } |
| 724 | 732 |
| 725 // Push arguments for the call. | 733 // Push arguments for the call. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 compiler->GenerateInstanceCall(deopt_id(), | 769 compiler->GenerateInstanceCall(deopt_id(), |
| 762 token_pos(), | 770 token_pos(), |
| 763 function_name, | 771 function_name, |
| 764 kNumArguments, | 772 kNumArguments, |
| 765 Array::ZoneHandle(), // No optional arguments. | 773 Array::ZoneHandle(), // No optional arguments. |
| 766 kNumArgsChecked, | 774 kNumArgsChecked, |
| 767 locs()); | 775 locs()); |
| 768 } | 776 } |
| 769 | 777 |
| 770 | 778 |
| 771 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 779 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler, |
| 772 BranchInstr* branch) { | 780 BranchInstr* branch) { |
| 773 if (operands_class_id() == kSmiCid) { | 781 if (operands_class_id() == kSmiCid) { |
| 774 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 782 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 775 return; | 783 return; |
| 776 } | 784 } |
| 777 if (operands_class_id() == kDoubleCid) { | 785 if (operands_class_id() == kDoubleCid) { |
| 778 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 786 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 779 return; | 787 return; |
| 780 } | 788 } |
| 781 EmitNativeCode(compiler); | 789 EmitNativeCode(compiler); |
| 782 __ CompareObject(EAX, compiler->bool_true()); | 790 __ CompareObject(EAX, compiler->bool_true()); |
| 783 branch->EmitBranchOnCondition(compiler, EQUAL); | 791 branch->EmitBranchOnCondition(compiler, EQUAL); |
| 784 } | 792 } |
| 785 | 793 |
| 786 | 794 |
| 787 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 795 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
| 788 const intptr_t kNumInputs = 0; | 796 const intptr_t kNumInputs = 0; |
| 789 const intptr_t kNumTemps = 3; | 797 const intptr_t kNumTemps = 3; |
| 790 LocationSummary* locs = | 798 LocationSummary* locs = |
| 791 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 799 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 792 locs->set_temp(0, Location::RegisterLocation(EAX)); | 800 locs->set_temp(0, Location::RegisterLocation(EAX)); |
| 793 locs->set_temp(1, Location::RegisterLocation(ECX)); | 801 locs->set_temp(1, Location::RegisterLocation(ECX)); |
| 794 locs->set_temp(2, Location::RegisterLocation(EDX)); | 802 locs->set_temp(2, Location::RegisterLocation(EDX)); |
| 795 locs->set_out(Location::RegisterLocation(EAX)); | 803 locs->set_out(Location::RegisterLocation(EAX)); |
| 796 return locs; | 804 return locs; |
| 797 } | 805 } |
| 798 | 806 |
| 799 | 807 |
| 800 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 808 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 801 ASSERT(locs()->temp(0).reg() == EAX); | 809 ASSERT(locs()->temp(0).reg() == EAX); |
| 802 ASSERT(locs()->temp(1).reg() == ECX); | 810 ASSERT(locs()->temp(1).reg() == ECX); |
| 803 ASSERT(locs()->temp(2).reg() == EDX); | 811 ASSERT(locs()->temp(2).reg() == EDX); |
| 804 Register result = locs()->out().reg(); | 812 Register result = locs()->out().reg(); |
| 805 | 813 |
| 806 // Push the result place holder initialized to NULL. | 814 // Push the result place holder initialized to NULL. |
| 807 __ PushObject(Object::ZoneHandle()); | 815 __ PushObject(Object::ZoneHandle()); |
| 808 // Pass a pointer to the first argument in EAX. | 816 // Pass a pointer to the first argument in EAX. |
| 809 intptr_t arg_count = argument_count(); | 817 intptr_t arg_count = argument_count(); |
| 810 if (is_native_instance_closure()) { | 818 if (is_native_instance_closure()) { |
| 811 arg_count += 1; | 819 arg_count += 1; |
| 812 } | 820 } |
| 813 if (!has_optional_parameters() && !is_native_instance_closure()) { | 821 if (!has_optional_parameters() && !is_native_instance_closure()) { |
| 814 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize)); | 822 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize)); |
| 815 } else { | 823 } else { |
| 816 __ leal(EAX, | 824 __ leal(EAX, |
| 817 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | 825 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
| 818 } | 826 } |
| 819 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 827 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
| 820 __ movl(EDX, Immediate(arg_count)); | 828 __ movl(EDX, Immediate(arg_count)); |
| 821 compiler->GenerateCall(token_pos(), | 829 compiler->GenerateCall(token_pos(), |
| 822 &StubCode::CallNativeCFunctionLabel(), | 830 &StubCode::CallNativeCFunctionLabel(), |
| 823 PcDescriptors::kOther, | 831 PcDescriptors::kOther, |
| 824 locs()); | 832 locs()); |
| 825 __ popl(result); | 833 __ popl(result); |
| 826 } | 834 } |
| 827 | 835 |
| 828 | 836 |
| 829 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 837 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { |
| 830 ASSERT((receiver_type() == kGrowableObjectArrayCid) || | 838 ASSERT((receiver_type() == kGrowableObjectArrayCid) || |
| 831 (receiver_type() == kArrayCid) || | 839 (receiver_type() == kArrayCid) || |
| 832 (receiver_type() == kImmutableArrayCid)); | 840 (receiver_type() == kImmutableArrayCid)); |
| 833 const intptr_t kNumInputs = 2; | 841 const intptr_t kNumInputs = 2; |
| 834 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0; | 842 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0; |
| 835 LocationSummary* locs = | 843 LocationSummary* locs = |
| 836 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 844 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 837 locs->set_in(0, Location::RequiresRegister()); | 845 locs->set_in(0, Location::RequiresRegister()); |
| 838 locs->set_in(1, Location::RequiresRegister()); | 846 locs->set_in(1, Location::RequiresRegister()); |
| 839 if (receiver_type() == kGrowableObjectArrayCid) { | 847 if (receiver_type() == kGrowableObjectArrayCid) { |
| 840 locs->set_temp(0, Location::RequiresRegister()); | 848 locs->set_temp(0, Location::RequiresRegister()); |
| 841 } | 849 } |
| 842 locs->set_out(Location::RequiresRegister()); | 850 locs->set_out(Location::RequiresRegister()); |
| 843 return locs; | 851 return locs; |
| 844 } | 852 } |
| 845 | 853 |
| 846 | 854 |
| 847 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 855 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 848 Register receiver = locs()->in(0).reg(); | 856 Register receiver = locs()->in(0).reg(); |
| 849 Register index = locs()->in(1).reg(); | 857 Register index = locs()->in(1).reg(); |
| 850 Register result = locs()->out().reg(); | 858 Register result = locs()->out().reg(); |
| 851 | 859 |
| 852 switch (receiver_type()) { | 860 switch (receiver_type()) { |
| 853 case kArrayCid: | 861 case kArrayCid: |
| 854 case kImmutableArrayCid: | 862 case kImmutableArrayCid: |
| 855 // Note that index is Smi, i.e, times 2. | 863 // Note that index is Smi, i.e, times 2. |
| 856 ASSERT(kSmiTagShift == 1); | 864 ASSERT(kSmiTagShift == 1); |
| 857 __ movl(result, FieldAddress(receiver, index, TIMES_2, sizeof(RawArray))); | 865 __ movl(result, FieldAddress(receiver, index, TIMES_2, sizeof(RawArray))); |
| 858 break; | 866 break; |
| 859 | 867 |
| 860 case kGrowableObjectArrayCid: { | 868 case kGrowableObjectArrayCid: { |
| 861 Register temp = locs()->temp(0).reg(); | 869 Register temp = locs()->temp(0).reg(); |
| 862 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); | 870 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); |
| 863 // Note that index is Smi, i.e, times 2. | 871 // Note that index is Smi, i.e, times 2. |
| 864 ASSERT(kSmiTagShift == 1); | 872 ASSERT(kSmiTagShift == 1); |
| 865 __ movl(result, FieldAddress(temp, index, TIMES_2, sizeof(RawArray))); | 873 __ movl(result, FieldAddress(temp, index, TIMES_2, sizeof(RawArray))); |
| 866 break; | 874 break; |
| 867 } | 875 } |
| 868 | 876 |
| 869 default: | 877 default: |
| 870 UNREACHABLE(); | 878 UNREACHABLE(); |
| 871 break; | 879 break; |
| 872 } | 880 } |
| 873 } | 881 } |
| 874 | 882 |
| 875 | 883 |
| 876 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 884 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { |
| 877 ASSERT((receiver_type() == kGrowableObjectArrayCid) || | 885 ASSERT((receiver_type() == kGrowableObjectArrayCid) || |
| 878 (receiver_type() == kArrayCid)); | 886 (receiver_type() == kArrayCid)); |
| 879 const intptr_t kNumInputs = 3; | 887 const intptr_t kNumInputs = 3; |
| 880 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0; | 888 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0; |
| 881 LocationSummary* locs = | 889 LocationSummary* locs = |
| 882 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 890 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 883 locs->set_in(0, Location::RequiresRegister()); | 891 locs->set_in(0, Location::RequiresRegister()); |
| 884 locs->set_in(1, Location::RequiresRegister()); | 892 locs->set_in(1, Location::RequiresRegister()); |
| 885 locs->set_in(2, Location::RequiresRegister()); | 893 locs->set_in(2, Location::RequiresRegister()); |
| 886 if (receiver_type() == kGrowableObjectArrayCid) { | 894 if (receiver_type() == kGrowableObjectArrayCid) { |
| 887 locs->set_temp(0, Location::RequiresRegister()); | 895 locs->set_temp(0, Location::RequiresRegister()); |
| 888 } | 896 } |
| 889 return locs; | 897 return locs; |
| 890 } | 898 } |
| 891 | 899 |
| 892 | 900 |
| 893 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 901 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 894 Register receiver = locs()->in(0).reg(); | 902 Register receiver = locs()->in(0).reg(); |
| 895 Register index = locs()->in(1).reg(); | 903 Register index = locs()->in(1).reg(); |
| 896 Register value = locs()->in(2).reg(); | 904 Register value = locs()->in(2).reg(); |
| 897 | 905 |
| 898 switch (receiver_type()) { | 906 switch (receiver_type()) { |
| 899 case kArrayCid: | 907 case kArrayCid: |
| 900 case kImmutableArrayCid: | 908 case kImmutableArrayCid: |
| 901 // Note that index is Smi, i.e, times 2. | 909 // Note that index is Smi, i.e, times 2. |
| 902 ASSERT(kSmiTagShift == 1); | 910 ASSERT(kSmiTagShift == 1); |
| 903 if (this->value()->NeedsStoreBuffer()) { | 911 if (this->value()->NeedsStoreBuffer()) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 928 break; | 936 break; |
| 929 } | 937 } |
| 930 | 938 |
| 931 default: | 939 default: |
| 932 UNREACHABLE(); | 940 UNREACHABLE(); |
| 933 break; | 941 break; |
| 934 } | 942 } |
| 935 } | 943 } |
| 936 | 944 |
| 937 | 945 |
| 938 LocationSummary* LoadInstanceFieldInstr::MakeLocationSummary() const { | 946 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { |
| 939 // TODO(fschneider): For this instruction the input register may be | 947 // TODO(fschneider): For this instruction the input register may be |
| 940 // reused for the result (but is not required to) because the input | 948 // reused for the result (but is not required to) because the input |
| 941 // is not used after the result is defined. We should consider adding | 949 // is not used after the result is defined. We should consider adding |
| 942 // this information to the input policy. | 950 // this information to the input policy. |
| 943 return LocationSummary::Make(1, | 951 return LocationSummary::Make(1, |
| 944 Location::RequiresRegister(), | 952 Location::RequiresRegister(), |
| 945 LocationSummary::kNoCall); | 953 LocationSummary::kNoCall); |
| 946 } | 954 } |
| 947 | 955 |
| 948 | 956 |
| 949 void LoadInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 957 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 950 Register instance_reg = locs()->in(0).reg(); | 958 Register instance_reg = locs()->in(0).reg(); |
| 951 Register result_reg = locs()->out().reg(); | 959 Register result_reg = locs()->out().reg(); |
| 952 __ movl(result_reg, FieldAddress(instance_reg, field().Offset())); | 960 __ movl(result_reg, FieldAddress(instance_reg, field().Offset())); |
| 953 } | 961 } |
| 954 | 962 |
| 955 | 963 |
| 956 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 964 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { |
| 957 const intptr_t kNumInputs = 2; | 965 const intptr_t kNumInputs = 2; |
| 958 const intptr_t num_temps = 0; | 966 const intptr_t num_temps = 0; |
| 959 LocationSummary* summary = | 967 LocationSummary* summary = |
| 960 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); | 968 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); |
| 961 summary->set_in(0, Location::RequiresRegister()); | 969 summary->set_in(0, Location::RequiresRegister()); |
| 962 summary->set_in(1, Location::RequiresRegister()); | 970 summary->set_in(1, Location::RequiresRegister()); |
| 963 return summary; | 971 return summary; |
| 964 } | 972 } |
| 965 | 973 |
| 966 | 974 |
| 967 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 975 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 968 Register instance_reg = locs()->in(0).reg(); | 976 Register instance_reg = locs()->in(0).reg(); |
| 969 Register value_reg = locs()->in(1).reg(); | 977 Register value_reg = locs()->in(1).reg(); |
| 970 if (this->value()->NeedsStoreBuffer()) { | 978 if (this->value()->NeedsStoreBuffer()) { |
| 971 __ StoreIntoObject(instance_reg, | 979 __ StoreIntoObject(instance_reg, |
| 972 FieldAddress(instance_reg, field().Offset()), value_reg); | 980 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 973 } else { | 981 } else { |
| 974 __ StoreIntoObjectNoBarrier(instance_reg, | 982 __ StoreIntoObjectNoBarrier(instance_reg, |
| 975 FieldAddress(instance_reg, field().Offset()), value_reg); | 983 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 976 } | 984 } |
| 977 } | 985 } |
| 978 | 986 |
| 979 | 987 |
| 980 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { | 988 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { |
| 981 return LocationSummary::Make(0, | 989 return LocationSummary::Make(0, |
| 982 Location::RequiresRegister(), | 990 Location::RequiresRegister(), |
| 983 LocationSummary::kNoCall); | 991 LocationSummary::kNoCall); |
| 984 } | 992 } |
| 985 | 993 |
| 986 | 994 |
| 987 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 995 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 988 Register result = locs()->out().reg(); | 996 Register result = locs()->out().reg(); |
| 989 __ LoadObject(result, field()); | 997 __ LoadObject(result, field()); |
| 990 __ movl(result, FieldAddress(result, Field::value_offset())); | 998 __ movl(result, FieldAddress(result, Field::value_offset())); |
| 991 } | 999 } |
| 992 | 1000 |
| 993 | 1001 |
| 994 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { | 1002 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { |
| 995 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); | 1003 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); |
| 996 locs->set_in(0, Location::RequiresRegister()); | 1004 locs->set_in(0, Location::RequiresRegister()); |
| 997 locs->set_temp(0, Location::RequiresRegister()); | 1005 locs->set_temp(0, Location::RequiresRegister()); |
| 998 locs->set_out(Location::SameAsFirstInput()); | 1006 locs->set_out(Location::SameAsFirstInput()); |
| 999 return locs; | 1007 return locs; |
| 1000 } | 1008 } |
| 1001 | 1009 |
| 1002 | 1010 |
| 1003 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1011 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1004 Register value = locs()->in(0).reg(); | 1012 Register value = locs()->in(0).reg(); |
| 1005 Register temp = locs()->temp(0).reg(); | 1013 Register temp = locs()->temp(0).reg(); |
| 1006 ASSERT(locs()->out().reg() == value); | 1014 ASSERT(locs()->out().reg() == value); |
| 1007 | 1015 |
| 1008 __ LoadObject(temp, field()); | 1016 __ LoadObject(temp, field()); |
| 1009 if (this->value()->NeedsStoreBuffer()) { | 1017 if (this->value()->NeedsStoreBuffer()) { |
| 1010 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); | 1018 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); |
| 1011 } else { | 1019 } else { |
| 1012 __ StoreIntoObjectNoBarrier( | 1020 __ StoreIntoObjectNoBarrier( |
| 1013 temp, FieldAddress(temp, Field::value_offset()), value); | 1021 temp, FieldAddress(temp, Field::value_offset()), value); |
| 1014 } | 1022 } |
| 1015 } | 1023 } |
| 1016 | 1024 |
| 1017 | 1025 |
| 1018 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { | 1026 LocationSummary* InstanceOfComp::MakeLocationSummary() const { |
| 1019 const intptr_t kNumInputs = 3; | 1027 const intptr_t kNumInputs = 3; |
| 1020 const intptr_t kNumTemps = 0; | 1028 const intptr_t kNumTemps = 0; |
| 1021 LocationSummary* summary = | 1029 LocationSummary* summary = |
| 1022 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1030 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1023 summary->set_in(0, Location::RegisterLocation(EAX)); | 1031 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1024 summary->set_in(1, Location::RegisterLocation(ECX)); | 1032 summary->set_in(1, Location::RegisterLocation(ECX)); |
| 1025 summary->set_in(2, Location::RegisterLocation(EDX)); | 1033 summary->set_in(2, Location::RegisterLocation(EDX)); |
| 1026 summary->set_out(Location::RegisterLocation(EAX)); | 1034 summary->set_out(Location::RegisterLocation(EAX)); |
| 1027 return summary; | 1035 return summary; |
| 1028 } | 1036 } |
| 1029 | 1037 |
| 1030 | 1038 |
| 1031 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1039 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1032 ASSERT(locs()->in(0).reg() == EAX); // Value. | 1040 ASSERT(locs()->in(0).reg() == EAX); // Value. |
| 1033 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. | 1041 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. |
| 1034 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. | 1042 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. |
| 1035 | 1043 |
| 1036 compiler->GenerateInstanceOf(token_pos(), | 1044 compiler->GenerateInstanceOf(token_pos(), |
| 1037 type(), | 1045 type(), |
| 1038 negate_result(), | 1046 negate_result(), |
| 1039 locs()); | 1047 locs()); |
| 1040 ASSERT(locs()->out().reg() == EAX); | 1048 ASSERT(locs()->out().reg() == EAX); |
| 1041 } | 1049 } |
| 1042 | 1050 |
| 1043 | 1051 |
| 1044 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { | 1052 LocationSummary* CreateArrayComp::MakeLocationSummary() const { |
| 1045 const intptr_t kNumInputs = 1; | 1053 const intptr_t kNumInputs = 1; |
| 1046 const intptr_t kNumTemps = 0; | 1054 const intptr_t kNumTemps = 0; |
| 1047 LocationSummary* locs = | 1055 LocationSummary* locs = |
| 1048 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1056 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1049 locs->set_in(0, Location::RegisterLocation(ECX)); | 1057 locs->set_in(0, Location::RegisterLocation(ECX)); |
| 1050 locs->set_out(Location::RegisterLocation(EAX)); | 1058 locs->set_out(Location::RegisterLocation(EAX)); |
| 1051 return locs; | 1059 return locs; |
| 1052 } | 1060 } |
| 1053 | 1061 |
| 1054 | 1062 |
| 1055 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1063 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1056 // Allocate the array. EDX = length, ECX = element type. | 1064 // Allocate the array. EDX = length, ECX = element type. |
| 1057 ASSERT(locs()->in(0).reg() == ECX); | 1065 ASSERT(locs()->in(0).reg() == ECX); |
| 1058 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount()))); | 1066 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount()))); |
| 1059 compiler->GenerateCall(token_pos(), | 1067 compiler->GenerateCall(token_pos(), |
| 1060 &StubCode::AllocateArrayLabel(), | 1068 &StubCode::AllocateArrayLabel(), |
| 1061 PcDescriptors::kOther, | 1069 PcDescriptors::kOther, |
| 1062 locs()); | 1070 locs()); |
| 1063 ASSERT(locs()->out().reg() == EAX); | 1071 ASSERT(locs()->out().reg() == EAX); |
| 1064 | 1072 |
| 1065 // Pop the element values from the stack into the array. | 1073 // Pop the element values from the stack into the array. |
| 1066 __ leal(EDX, FieldAddress(EAX, Array::data_offset())); | 1074 __ leal(EDX, FieldAddress(EAX, Array::data_offset())); |
| 1067 for (int i = ArgumentCount() - 1; i >= 0; --i) { | 1075 for (int i = ArgumentCount() - 1; i >= 0; --i) { |
| 1068 __ popl(Address(EDX, i * kWordSize)); | 1076 __ popl(Address(EDX, i * kWordSize)); |
| 1069 } | 1077 } |
| 1070 } | 1078 } |
| 1071 | 1079 |
| 1072 | 1080 |
| 1073 LocationSummary* | 1081 LocationSummary* |
| 1074 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { | 1082 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { |
| 1075 const intptr_t kNumInputs = 2; | 1083 const intptr_t kNumInputs = 2; |
| 1076 const intptr_t kNumTemps = 0; | 1084 const intptr_t kNumTemps = 0; |
| 1077 LocationSummary* locs = | 1085 LocationSummary* locs = |
| 1078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1086 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1079 locs->set_in(0, Location::RegisterLocation(EAX)); | 1087 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 1080 locs->set_in(1, Location::RegisterLocation(ECX)); | 1088 locs->set_in(1, Location::RegisterLocation(ECX)); |
| 1081 locs->set_out(Location::RegisterLocation(EAX)); | 1089 locs->set_out(Location::RegisterLocation(EAX)); |
| 1082 return locs; | 1090 return locs; |
| 1083 } | 1091 } |
| 1084 | 1092 |
| 1085 | 1093 |
| 1086 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( | 1094 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( |
| 1087 FlowGraphCompiler* compiler) { | 1095 FlowGraphCompiler* compiler) { |
| 1088 const Class& cls = Class::ZoneHandle(constructor().Owner()); | 1096 const Class& cls = Class::ZoneHandle(constructor().Owner()); |
| 1089 Register type_arguments = locs()->in(0).reg(); | 1097 Register type_arguments = locs()->in(0).reg(); |
| 1090 Register instantiator_type_arguments = locs()->in(1).reg(); | 1098 Register instantiator_type_arguments = locs()->in(1).reg(); |
| 1091 Register result = locs()->out().reg(); | 1099 Register result = locs()->out().reg(); |
| 1092 | 1100 |
| 1093 // Push the result place holder initialized to NULL. | 1101 // Push the result place holder initialized to NULL. |
| 1094 __ PushObject(Object::ZoneHandle()); | 1102 __ PushObject(Object::ZoneHandle()); |
| 1095 __ PushObject(cls); | 1103 __ PushObject(cls); |
| 1096 __ pushl(type_arguments); | 1104 __ pushl(type_arguments); |
| 1097 __ pushl(instantiator_type_arguments); | 1105 __ pushl(instantiator_type_arguments); |
| 1098 compiler->GenerateCallRuntime(token_pos(), | 1106 compiler->GenerateCallRuntime(token_pos(), |
| 1099 kAllocateObjectWithBoundsCheckRuntimeEntry, | 1107 kAllocateObjectWithBoundsCheckRuntimeEntry, |
| 1100 locs()); | 1108 locs()); |
| 1101 // Pop instantiator type arguments, type arguments, and class. | 1109 // Pop instantiator type arguments, type arguments, and class. |
| 1102 // source location. | 1110 // source location. |
| 1103 __ Drop(3); | 1111 __ Drop(3); |
| 1104 __ popl(result); // Pop new instance. | 1112 __ popl(result); // Pop new instance. |
| 1105 } | 1113 } |
| 1106 | 1114 |
| 1107 | 1115 |
| 1108 LocationSummary* LoadVMFieldInstr::MakeLocationSummary() const { | 1116 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
| 1109 return LocationSummary::Make(1, | 1117 return LocationSummary::Make(1, |
| 1110 Location::RequiresRegister(), | 1118 Location::RequiresRegister(), |
| 1111 LocationSummary::kNoCall); | 1119 LocationSummary::kNoCall); |
| 1112 } | 1120 } |
| 1113 | 1121 |
| 1114 | 1122 |
| 1115 void LoadVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1123 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1116 Register instance_reg = locs()->in(0).reg(); | 1124 Register instance_reg = locs()->in(0).reg(); |
| 1117 Register result_reg = locs()->out().reg(); | 1125 Register result_reg = locs()->out().reg(); |
| 1118 | 1126 |
| 1119 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes())); | 1127 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes())); |
| 1120 } | 1128 } |
| 1121 | 1129 |
| 1122 | 1130 |
| 1123 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { | 1131 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { |
| 1124 const intptr_t kNumInputs = 1; | 1132 const intptr_t kNumInputs = 1; |
| 1125 const intptr_t kNumTemps = 1; | 1133 const intptr_t kNumTemps = 1; |
| 1126 LocationSummary* locs = | 1134 LocationSummary* locs = |
| 1127 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1135 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1128 locs->set_in(0, Location::RegisterLocation(EAX)); | 1136 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 1129 locs->set_temp(0, Location::RegisterLocation(ECX)); | 1137 locs->set_temp(0, Location::RegisterLocation(ECX)); |
| 1130 locs->set_out(Location::RegisterLocation(EAX)); | 1138 locs->set_out(Location::RegisterLocation(EAX)); |
| 1131 return locs; | 1139 return locs; |
| 1132 } | 1140 } |
| 1133 | 1141 |
| 1134 | 1142 |
| 1135 void InstantiateTypeArgumentsInstr::EmitNativeCode( | 1143 void InstantiateTypeArgumentsComp::EmitNativeCode( |
| 1136 FlowGraphCompiler* compiler) { | 1144 FlowGraphCompiler* compiler) { |
| 1137 Register instantiator_reg = locs()->in(0).reg(); | 1145 Register instantiator_reg = locs()->in(0).reg(); |
| 1138 Register temp = locs()->temp(0).reg(); | 1146 Register temp = locs()->temp(0).reg(); |
| 1139 Register result_reg = locs()->out().reg(); | 1147 Register result_reg = locs()->out().reg(); |
| 1140 | 1148 |
| 1141 // 'instantiator_reg' is the instantiator AbstractTypeArguments object | 1149 // 'instantiator_reg' is the instantiator AbstractTypeArguments object |
| 1142 // (or null). | 1150 // (or null). |
| 1143 // If the instantiator is null and if the type argument vector | 1151 // If the instantiator is null and if the type argument vector |
| 1144 // instantiated from null becomes a vector of Dynamic, then use null as | 1152 // instantiated from null becomes a vector of Dynamic, then use null as |
| 1145 // the type arguments. | 1153 // the type arguments. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1175 locs()); | 1183 locs()); |
| 1176 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 1184 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
| 1177 __ popl(result_reg); // Pop instantiated type arguments. | 1185 __ popl(result_reg); // Pop instantiated type arguments. |
| 1178 __ Bind(&type_arguments_instantiated); | 1186 __ Bind(&type_arguments_instantiated); |
| 1179 ASSERT(instantiator_reg == result_reg); | 1187 ASSERT(instantiator_reg == result_reg); |
| 1180 // 'result_reg': Instantiated type arguments. | 1188 // 'result_reg': Instantiated type arguments. |
| 1181 } | 1189 } |
| 1182 | 1190 |
| 1183 | 1191 |
| 1184 LocationSummary* | 1192 LocationSummary* |
| 1185 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { | 1193 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { |
| 1186 const intptr_t kNumInputs = 1; | 1194 const intptr_t kNumInputs = 1; |
| 1187 const intptr_t kNumTemps = 1; | 1195 const intptr_t kNumTemps = 1; |
| 1188 LocationSummary* locs = | 1196 LocationSummary* locs = |
| 1189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1197 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1190 locs->set_in(0, Location::RequiresRegister()); | 1198 locs->set_in(0, Location::RequiresRegister()); |
| 1191 locs->set_out(Location::SameAsFirstInput()); | 1199 locs->set_out(Location::SameAsFirstInput()); |
| 1192 locs->set_temp(0, Location::RequiresRegister()); | 1200 locs->set_temp(0, Location::RequiresRegister()); |
| 1193 return locs; | 1201 return locs; |
| 1194 } | 1202 } |
| 1195 | 1203 |
| 1196 | 1204 |
| 1197 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( | 1205 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( |
| 1198 FlowGraphCompiler* compiler) { | 1206 FlowGraphCompiler* compiler) { |
| 1199 Register instantiator_reg = locs()->in(0).reg(); | 1207 Register instantiator_reg = locs()->in(0).reg(); |
| 1200 Register result_reg = locs()->out().reg(); | 1208 Register result_reg = locs()->out().reg(); |
| 1201 ASSERT(instantiator_reg == result_reg); | 1209 ASSERT(instantiator_reg == result_reg); |
| 1202 Register temp_reg = locs()->temp(0).reg(); | 1210 Register temp_reg = locs()->temp(0).reg(); |
| 1203 | 1211 |
| 1204 // instantiator_reg is the instantiator type argument vector, i.e. an | 1212 // instantiator_reg is the instantiator type argument vector, i.e. an |
| 1205 // AbstractTypeArguments object (or null). | 1213 // AbstractTypeArguments object (or null). |
| 1206 // If the instantiator is null and if the type argument vector | 1214 // If the instantiator is null and if the type argument vector |
| 1207 // instantiated from null becomes a vector of Dynamic, then use null as | 1215 // instantiated from null becomes a vector of Dynamic, then use null as |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1233 // In the non-factory case, we rely on the allocation stub to | 1241 // In the non-factory case, we rely on the allocation stub to |
| 1234 // instantiate the type arguments. | 1242 // instantiate the type arguments. |
| 1235 __ LoadObject(result_reg, type_arguments()); | 1243 __ LoadObject(result_reg, type_arguments()); |
| 1236 // result_reg: uninstantiated type arguments. | 1244 // result_reg: uninstantiated type arguments. |
| 1237 __ Bind(&type_arguments_instantiated); | 1245 __ Bind(&type_arguments_instantiated); |
| 1238 // result_reg: uninstantiated or instantiated type arguments. | 1246 // result_reg: uninstantiated or instantiated type arguments. |
| 1239 } | 1247 } |
| 1240 | 1248 |
| 1241 | 1249 |
| 1242 LocationSummary* | 1250 LocationSummary* |
| 1243 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { | 1251 ExtractConstructorInstantiatorComp::MakeLocationSummary() const { |
| 1244 const intptr_t kNumInputs = 1; | 1252 const intptr_t kNumInputs = 1; |
| 1245 const intptr_t kNumTemps = 1; | 1253 const intptr_t kNumTemps = 1; |
| 1246 LocationSummary* locs = | 1254 LocationSummary* locs = |
| 1247 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1255 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1248 locs->set_in(0, Location::RequiresRegister()); | 1256 locs->set_in(0, Location::RequiresRegister()); |
| 1249 locs->set_out(Location::SameAsFirstInput()); | 1257 locs->set_out(Location::SameAsFirstInput()); |
| 1250 locs->set_temp(0, Location::RequiresRegister()); | 1258 locs->set_temp(0, Location::RequiresRegister()); |
| 1251 return locs; | 1259 return locs; |
| 1252 } | 1260 } |
| 1253 | 1261 |
| 1254 | 1262 |
| 1255 void ExtractConstructorInstantiatorInstr::EmitNativeCode( | 1263 void ExtractConstructorInstantiatorComp::EmitNativeCode( |
| 1256 FlowGraphCompiler* compiler) { | 1264 FlowGraphCompiler* compiler) { |
| 1257 Register instantiator_reg = locs()->in(0).reg(); | 1265 Register instantiator_reg = locs()->in(0).reg(); |
| 1258 ASSERT(locs()->out().reg() == instantiator_reg); | 1266 ASSERT(locs()->out().reg() == instantiator_reg); |
| 1259 Register temp_reg = locs()->temp(0).reg(); | 1267 Register temp_reg = locs()->temp(0).reg(); |
| 1260 | 1268 |
| 1261 // instantiator_reg is the instantiator AbstractTypeArguments object | 1269 // instantiator_reg is the instantiator AbstractTypeArguments object |
| 1262 // (or null). If the instantiator is null and if the type argument vector | 1270 // (or null). If the instantiator is null and if the type argument vector |
| 1263 // instantiated from null becomes a vector of Dynamic, then use null as | 1271 // instantiated from null becomes a vector of Dynamic, then use null as |
| 1264 // the type arguments and do not pass the instantiator. | 1272 // the type arguments and do not pass the instantiator. |
| 1265 Label done; | 1273 Label done; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1299 // The instantiator was used in VisitExtractConstructorTypeArguments as the | 1307 // The instantiator was used in VisitExtractConstructorTypeArguments as the |
| 1300 // instantiated type arguments, no proper instantiator needed. | 1308 // instantiated type arguments, no proper instantiator needed. |
| 1301 __ movl(instantiator_reg, | 1309 __ movl(instantiator_reg, |
| 1302 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1310 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
| 1303 } | 1311 } |
| 1304 __ Bind(&done); | 1312 __ Bind(&done); |
| 1305 // instantiator_reg: instantiator or kNoInstantiator. | 1313 // instantiator_reg: instantiator or kNoInstantiator. |
| 1306 } | 1314 } |
| 1307 | 1315 |
| 1308 | 1316 |
| 1309 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { | 1317 LocationSummary* AllocateContextComp::MakeLocationSummary() const { |
| 1310 const intptr_t kNumInputs = 0; | 1318 const intptr_t kNumInputs = 0; |
| 1311 const intptr_t kNumTemps = 1; | 1319 const intptr_t kNumTemps = 1; |
| 1312 LocationSummary* locs = | 1320 LocationSummary* locs = |
| 1313 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1321 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1314 locs->set_temp(0, Location::RegisterLocation(EDX)); | 1322 locs->set_temp(0, Location::RegisterLocation(EDX)); |
| 1315 locs->set_out(Location::RegisterLocation(EAX)); | 1323 locs->set_out(Location::RegisterLocation(EAX)); |
| 1316 return locs; | 1324 return locs; |
| 1317 } | 1325 } |
| 1318 | 1326 |
| 1319 | 1327 |
| 1320 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1328 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1321 ASSERT(locs()->temp(0).reg() == EDX); | 1329 ASSERT(locs()->temp(0).reg() == EDX); |
| 1322 ASSERT(locs()->out().reg() == EAX); | 1330 ASSERT(locs()->out().reg() == EAX); |
| 1323 | 1331 |
| 1324 __ movl(EDX, Immediate(num_context_variables())); | 1332 __ movl(EDX, Immediate(num_context_variables())); |
| 1325 const ExternalLabel label("alloc_context", | 1333 const ExternalLabel label("alloc_context", |
| 1326 StubCode::AllocateContextEntryPoint()); | 1334 StubCode::AllocateContextEntryPoint()); |
| 1327 compiler->GenerateCall(token_pos(), | 1335 compiler->GenerateCall(token_pos(), |
| 1328 &label, | 1336 &label, |
| 1329 PcDescriptors::kOther, | 1337 PcDescriptors::kOther, |
| 1330 locs()); | 1338 locs()); |
| 1331 } | 1339 } |
| 1332 | 1340 |
| 1333 | 1341 |
| 1334 LocationSummary* CloneContextInstr::MakeLocationSummary() const { | 1342 LocationSummary* CloneContextComp::MakeLocationSummary() const { |
| 1335 const intptr_t kNumInputs = 1; | 1343 const intptr_t kNumInputs = 1; |
| 1336 const intptr_t kNumTemps = 0; | 1344 const intptr_t kNumTemps = 0; |
| 1337 LocationSummary* locs = | 1345 LocationSummary* locs = |
| 1338 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1346 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1339 locs->set_in(0, Location::RegisterLocation(EAX)); | 1347 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 1340 locs->set_out(Location::RegisterLocation(EAX)); | 1348 locs->set_out(Location::RegisterLocation(EAX)); |
| 1341 return locs; | 1349 return locs; |
| 1342 } | 1350 } |
| 1343 | 1351 |
| 1344 | 1352 |
| 1345 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1353 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1346 Register context_value = locs()->in(0).reg(); | 1354 Register context_value = locs()->in(0).reg(); |
| 1347 Register result = locs()->out().reg(); | 1355 Register result = locs()->out().reg(); |
| 1348 | 1356 |
| 1349 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1357 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 1350 __ pushl(context_value); | 1358 __ pushl(context_value); |
| 1351 compiler->GenerateCallRuntime(token_pos(), | 1359 compiler->GenerateCallRuntime(token_pos(), |
| 1352 kCloneContextRuntimeEntry, | 1360 kCloneContextRuntimeEntry, |
| 1353 locs()); | 1361 locs()); |
| 1354 __ popl(result); // Remove argument. | 1362 __ popl(result); // Remove argument. |
| 1355 __ popl(result); // Get result (cloned context). | 1363 __ popl(result); // Get result (cloned context). |
| 1356 } | 1364 } |
| 1357 | 1365 |
| 1358 | 1366 |
| 1359 LocationSummary* CatchEntryInstr::MakeLocationSummary() const { | 1367 LocationSummary* CatchEntryComp::MakeLocationSummary() const { |
| 1360 return LocationSummary::Make(0, | 1368 return LocationSummary::Make(0, |
| 1361 Location::NoLocation(), | 1369 Location::NoLocation(), |
| 1362 LocationSummary::kNoCall); | 1370 LocationSummary::kNoCall); |
| 1363 } | 1371 } |
| 1364 | 1372 |
| 1365 | 1373 |
| 1366 // Restore stack and initialize the two exception variables: | 1374 // Restore stack and initialize the two exception variables: |
| 1367 // exception and stack trace variables. | 1375 // exception and stack trace variables. |
| 1368 void CatchEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1376 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1369 // Restore RSP from RBP as we are coming from a throw and the code for | 1377 // Restore RSP from RBP as we are coming from a throw and the code for |
| 1370 // popping arguments has not been run. | 1378 // popping arguments has not been run. |
| 1371 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; | 1379 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; |
| 1372 ASSERT(locals_space_size >= 0); | 1380 ASSERT(locals_space_size >= 0); |
| 1373 const intptr_t offset_size = | 1381 const intptr_t offset_size = |
| 1374 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; | 1382 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; |
| 1375 __ leal(ESP, Address(EBP, offset_size)); | 1383 __ leal(ESP, Address(EBP, offset_size)); |
| 1376 | 1384 |
| 1377 ASSERT(!exception_var().is_captured()); | 1385 ASSERT(!exception_var().is_captured()); |
| 1378 ASSERT(!stacktrace_var().is_captured()); | 1386 ASSERT(!stacktrace_var().is_captured()); |
| 1379 __ movl(Address(EBP, exception_var().index() * kWordSize), | 1387 __ movl(Address(EBP, exception_var().index() * kWordSize), |
| 1380 kExceptionObjectReg); | 1388 kExceptionObjectReg); |
| 1381 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), | 1389 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), |
| 1382 kStackTraceObjectReg); | 1390 kStackTraceObjectReg); |
| 1383 } | 1391 } |
| 1384 | 1392 |
| 1385 | 1393 |
| 1386 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { | 1394 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { |
| 1387 const intptr_t kNumInputs = 0; | 1395 const intptr_t kNumInputs = 0; |
| 1388 const intptr_t kNumTemps = 0; | 1396 const intptr_t kNumTemps = 0; |
| 1389 LocationSummary* summary = | 1397 LocationSummary* summary = |
| 1390 new LocationSummary(kNumInputs, | 1398 new LocationSummary(kNumInputs, |
| 1391 kNumTemps, | 1399 kNumTemps, |
| 1392 LocationSummary::kCallOnSlowPath); | 1400 LocationSummary::kCallOnSlowPath); |
| 1393 return summary; | 1401 return summary; |
| 1394 } | 1402 } |
| 1395 | 1403 |
| 1396 | 1404 |
| 1397 class CheckStackOverflowSlowPath : public SlowPathCode { | 1405 class CheckStackOverflowSlowPath : public SlowPathCode { |
| 1398 public: | 1406 public: |
| 1399 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) | 1407 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation) |
| 1400 : instruction_(instruction) { } | 1408 : computation_(computation) { } |
| 1401 | 1409 |
| 1402 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1410 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1403 __ Bind(entry_label()); | 1411 __ Bind(entry_label()); |
| 1404 compiler->SaveLiveRegisters(instruction_->locs()); | 1412 compiler->SaveLiveRegisters(computation_->locs()); |
| 1405 compiler->GenerateCallRuntime(instruction_->token_pos(), | 1413 compiler->GenerateCallRuntime(computation_->token_pos(), |
| 1406 kStackOverflowRuntimeEntry, | 1414 kStackOverflowRuntimeEntry, |
| 1407 instruction_->locs()); | 1415 computation_->locs()); |
| 1408 compiler->RestoreLiveRegisters(instruction_->locs()); | 1416 compiler->RestoreLiveRegisters(computation_->locs()); |
| 1409 __ jmp(exit_label()); | 1417 __ jmp(exit_label()); |
| 1410 } | 1418 } |
| 1411 | 1419 |
| 1412 private: | 1420 private: |
| 1413 CheckStackOverflowInstr* instruction_; | 1421 CheckStackOverflowComp* computation_; |
| 1414 }; | 1422 }; |
| 1415 | 1423 |
| 1416 | 1424 |
| 1417 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1425 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1418 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); | 1426 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); |
| 1419 compiler->AddSlowPathCode(slow_path); | 1427 compiler->AddSlowPathCode(slow_path); |
| 1420 | 1428 |
| 1421 __ cmpl(ESP, | 1429 __ cmpl(ESP, |
| 1422 Address::Absolute(Isolate::Current()->stack_limit_address())); | 1430 Address::Absolute(Isolate::Current()->stack_limit_address())); |
| 1423 __ j(BELOW_EQUAL, slow_path->entry_label()); | 1431 __ j(BELOW_EQUAL, slow_path->entry_label()); |
| 1424 __ Bind(slow_path->exit_label()); | 1432 __ Bind(slow_path->exit_label()); |
| 1425 } | 1433 } |
| 1426 | 1434 |
| 1427 | 1435 |
| 1428 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { | 1436 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const { |
| 1429 const intptr_t kNumInputs = 2; | 1437 const intptr_t kNumInputs = 2; |
| 1430 if (op_kind() == Token::kTRUNCDIV) { | 1438 if (op_kind() == Token::kTRUNCDIV) { |
| 1431 const intptr_t kNumTemps = 3; | 1439 const intptr_t kNumTemps = 3; |
| 1432 LocationSummary* summary = | 1440 LocationSummary* summary = |
| 1433 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1441 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1434 summary->set_in(0, Location::RegisterLocation(EAX)); | 1442 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1435 summary->set_in(1, Location::RegisterLocation(ECX)); | 1443 summary->set_in(1, Location::RegisterLocation(ECX)); |
| 1436 summary->set_out(Location::SameAsFirstInput()); | 1444 summary->set_out(Location::SameAsFirstInput()); |
| 1437 summary->set_temp(0, Location::RegisterLocation(EBX)); | 1445 summary->set_temp(0, Location::RegisterLocation(EBX)); |
| 1438 // Will be used for for sign extension. | 1446 // Will be used for for sign extension. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1463 LocationSummary* summary = | 1471 LocationSummary* summary = |
| 1464 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1472 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1465 summary->set_in(0, Location::RequiresRegister()); | 1473 summary->set_in(0, Location::RequiresRegister()); |
| 1466 summary->set_in(1, Location::RegisterOrConstant(right())); | 1474 summary->set_in(1, Location::RegisterOrConstant(right())); |
| 1467 summary->set_out(Location::SameAsFirstInput()); | 1475 summary->set_out(Location::SameAsFirstInput()); |
| 1468 return summary; | 1476 return summary; |
| 1469 } | 1477 } |
| 1470 } | 1478 } |
| 1471 | 1479 |
| 1472 | 1480 |
| 1473 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1481 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1474 Register left = locs()->in(0).reg(); | 1482 Register left = locs()->in(0).reg(); |
| 1475 Register result = locs()->out().reg(); | 1483 Register result = locs()->out().reg(); |
| 1476 ASSERT(left == result); | 1484 ASSERT(left == result); |
| 1477 Label* deopt = NULL; | 1485 Label* deopt = NULL; |
| 1478 switch (op_kind()) { | 1486 switch (op_kind()) { |
| 1479 case Token::kBIT_AND: | 1487 case Token::kBIT_AND: |
| 1480 case Token::kBIT_OR: | 1488 case Token::kBIT_OR: |
| 1481 case Token::kBIT_XOR: | 1489 case Token::kBIT_XOR: |
| 1482 // Can't deoptimize. Arguments are already checked for smi. | 1490 // Can't deoptimize. Arguments are already checked for smi. |
| 1483 break; | 1491 break; |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1684 UNREACHABLE(); | 1692 UNREACHABLE(); |
| 1685 break; | 1693 break; |
| 1686 } | 1694 } |
| 1687 default: | 1695 default: |
| 1688 UNREACHABLE(); | 1696 UNREACHABLE(); |
| 1689 break; | 1697 break; |
| 1690 } | 1698 } |
| 1691 } | 1699 } |
| 1692 | 1700 |
| 1693 | 1701 |
| 1694 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { | 1702 LocationSummary* BinaryMintOpComp::MakeLocationSummary() const { |
| 1695 const intptr_t kNumInputs = 2; | 1703 const intptr_t kNumInputs = 2; |
| 1696 ASSERT(op_kind() == Token::kBIT_AND); | 1704 ASSERT(op_kind() == Token::kBIT_AND); |
| 1697 const intptr_t kNumTemps = 1; | 1705 const intptr_t kNumTemps = 1; |
| 1698 LocationSummary* summary = | 1706 LocationSummary* summary = |
| 1699 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1707 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1700 summary->set_in(0, Location::RegisterLocation(EAX)); | 1708 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1701 summary->set_in(1, Location::RegisterLocation(ECX)); | 1709 summary->set_in(1, Location::RegisterLocation(ECX)); |
| 1702 summary->set_temp(0, Location::RegisterLocation(EDX)); | 1710 summary->set_temp(0, Location::RegisterLocation(EDX)); |
| 1703 summary->set_out(Location::RegisterLocation(EAX)); | 1711 summary->set_out(Location::RegisterLocation(EAX)); |
| 1704 return summary; | 1712 return summary; |
| 1705 } | 1713 } |
| 1706 | 1714 |
| 1707 | 1715 |
| 1708 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1716 void BinaryMintOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1709 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi | 1717 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi |
| 1710 // receiver and a Mint or Smi argument. We fall back to the run time call if | 1718 // receiver and a Mint or Smi argument. We fall back to the run time call if |
| 1711 // both receiver and argument are Mint or if one of them is Mint and the other | 1719 // both receiver and argument are Mint or if one of them is Mint and the other |
| 1712 // is a negative Smi. | 1720 // is a negative Smi. |
| 1713 Register left = locs()->in(0).reg(); | 1721 Register left = locs()->in(0).reg(); |
| 1714 Register right = locs()->in(1).reg(); | 1722 Register right = locs()->in(1).reg(); |
| 1715 Register result = locs()->out().reg(); | 1723 Register result = locs()->out().reg(); |
| 1716 Register temp = locs()->temp(0).reg(); | 1724 Register temp = locs()->temp(0).reg(); |
| 1717 ASSERT(left == result); | 1725 ASSERT(left == result); |
| 1718 ASSERT(op_kind() == Token::kBIT_AND); | 1726 ASSERT(op_kind() == Token::kBIT_AND); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1788 instance_call()->ArgumentCount(), | 1796 instance_call()->ArgumentCount(), |
| 1789 instance_call()->argument_names(), | 1797 instance_call()->argument_names(), |
| 1790 locs()); | 1798 locs()); |
| 1791 ASSERT(result == EAX); | 1799 ASSERT(result == EAX); |
| 1792 } | 1800 } |
| 1793 } | 1801 } |
| 1794 __ Bind(&done); | 1802 __ Bind(&done); |
| 1795 } | 1803 } |
| 1796 | 1804 |
| 1797 | 1805 |
| 1798 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { | 1806 LocationSummary* CheckEitherNonSmiComp::MakeLocationSummary() const { |
| 1799 ASSERT((left()->ResultCid() != kDoubleCid) && | 1807 ASSERT((left()->ResultCid() != kDoubleCid) && |
| 1800 (right()->ResultCid() != kDoubleCid)); | 1808 (right()->ResultCid() != kDoubleCid)); |
| 1801 const intptr_t kNumInputs = 2; | 1809 const intptr_t kNumInputs = 2; |
| 1802 const intptr_t kNumTemps = 1; | 1810 const intptr_t kNumTemps = 1; |
| 1803 LocationSummary* summary = | 1811 LocationSummary* summary = |
| 1804 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1812 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1805 summary->set_in(0, Location::RequiresRegister()); | 1813 summary->set_in(0, Location::RequiresRegister()); |
| 1806 summary->set_in(1, Location::RequiresRegister()); | 1814 summary->set_in(1, Location::RequiresRegister()); |
| 1807 summary->set_temp(0, Location::RequiresRegister()); | 1815 summary->set_temp(0, Location::RequiresRegister()); |
| 1808 return summary; | 1816 return summary; |
| 1809 } | 1817 } |
| 1810 | 1818 |
| 1811 | 1819 |
| 1812 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1820 void CheckEitherNonSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1813 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryDoubleOp); | 1821 Label* deopt = compiler->AddDeoptStub(instance_call_->deopt_id(), |
| 1822 kDeoptBinaryDoubleOp); |
| 1823 |
| 1814 Register temp = locs()->temp(0).reg(); | 1824 Register temp = locs()->temp(0).reg(); |
| 1815 __ movl(temp, locs()->in(0).reg()); | 1825 __ movl(temp, locs()->in(0).reg()); |
| 1816 __ orl(temp, locs()->in(1).reg()); | 1826 __ orl(temp, locs()->in(1).reg()); |
| 1817 __ testl(temp, Immediate(kSmiTagMask)); | 1827 __ testl(temp, Immediate(kSmiTagMask)); |
| 1818 __ j(ZERO, deopt); | 1828 __ j(ZERO, deopt); |
| 1819 } | 1829 } |
| 1820 | 1830 |
| 1821 | 1831 |
| 1822 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { | 1832 LocationSummary* BoxDoubleComp::MakeLocationSummary() const { |
| 1823 const intptr_t kNumInputs = 1; | 1833 const intptr_t kNumInputs = 1; |
| 1824 const intptr_t kNumTemps = 0; | 1834 const intptr_t kNumTemps = 0; |
| 1825 LocationSummary* summary = | 1835 LocationSummary* summary = |
| 1826 new LocationSummary(kNumInputs, | 1836 new LocationSummary(kNumInputs, |
| 1827 kNumTemps, | 1837 kNumTemps, |
| 1828 LocationSummary::kCallOnSlowPath); | 1838 LocationSummary::kCallOnSlowPath); |
| 1829 summary->set_in(0, Location::RequiresXmmRegister()); | 1839 summary->set_in(0, Location::RequiresXmmRegister()); |
| 1830 summary->set_out(Location::RequiresRegister()); | 1840 summary->set_out(Location::RequiresRegister()); |
| 1831 return summary; | 1841 return summary; |
| 1832 } | 1842 } |
| 1833 | 1843 |
| 1834 | 1844 |
| 1835 class BoxDoubleSlowPath : public SlowPathCode { | 1845 class BoxDoubleSlowPath : public SlowPathCode { |
| 1836 public: | 1846 public: |
| 1837 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction) | 1847 explicit BoxDoubleSlowPath(BoxDoubleComp* computation) |
| 1838 : instruction_(instruction) { } | 1848 : computation_(computation) { } |
| 1839 | 1849 |
| 1840 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1850 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1841 __ Bind(entry_label()); | 1851 __ Bind(entry_label()); |
| 1842 const Class& double_class = compiler->double_class(); | 1852 const Class& double_class = compiler->double_class(); |
| 1843 const Code& stub = | 1853 const Code& stub = |
| 1844 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1854 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1845 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 1855 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1846 | 1856 |
| 1847 LocationSummary* locs = instruction_->locs(); | 1857 LocationSummary* locs = computation_->locs(); |
| 1848 locs->live_registers()->Remove(locs->out()); | 1858 locs->live_registers()->Remove(locs->out()); |
| 1849 | 1859 |
| 1850 compiler->SaveLiveRegisters(locs); | 1860 compiler->SaveLiveRegisters(locs); |
| 1851 compiler->GenerateCall(instruction_->token_pos(), | 1861 compiler->GenerateCall(computation_->token_pos(), |
| 1852 &label, | 1862 &label, |
| 1853 PcDescriptors::kOther, | 1863 PcDescriptors::kOther, |
| 1854 locs); | 1864 locs); |
| 1855 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX); | 1865 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX); |
| 1856 compiler->RestoreLiveRegisters(locs); | 1866 compiler->RestoreLiveRegisters(locs); |
| 1857 | 1867 |
| 1858 __ jmp(exit_label()); | 1868 __ jmp(exit_label()); |
| 1859 } | 1869 } |
| 1860 | 1870 |
| 1861 private: | 1871 private: |
| 1862 BoxDoubleInstr* instruction_; | 1872 BoxDoubleComp* computation_; |
| 1863 }; | 1873 }; |
| 1864 | 1874 |
| 1865 | 1875 |
| 1866 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1876 void BoxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1867 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 1877 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 1868 compiler->AddSlowPathCode(slow_path); | 1878 compiler->AddSlowPathCode(slow_path); |
| 1869 | 1879 |
| 1870 Register out_reg = locs()->out().reg(); | 1880 Register out_reg = locs()->out().reg(); |
| 1871 XmmRegister value = locs()->in(0).xmm_reg(); | 1881 XmmRegister value = locs()->in(0).xmm_reg(); |
| 1872 | 1882 |
| 1873 AssemblerMacros::TryAllocate(compiler->assembler(), | 1883 AssemblerMacros::TryAllocate(compiler->assembler(), |
| 1874 compiler->double_class(), | 1884 compiler->double_class(), |
| 1875 slow_path->entry_label(), | 1885 slow_path->entry_label(), |
| 1876 Assembler::kFarJump, | 1886 Assembler::kFarJump, |
| 1877 out_reg); | 1887 out_reg); |
| 1878 __ Bind(slow_path->exit_label()); | 1888 __ Bind(slow_path->exit_label()); |
| 1879 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); | 1889 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); |
| 1880 } | 1890 } |
| 1881 | 1891 |
| 1882 | 1892 |
| 1883 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { | 1893 LocationSummary* UnboxDoubleComp::MakeLocationSummary() const { |
| 1884 const intptr_t v_cid = value()->ResultCid(); | 1894 const intptr_t v_cid = value()->ResultCid(); |
| 1885 | 1895 |
| 1886 const intptr_t kNumInputs = 1; | 1896 const intptr_t kNumInputs = 1; |
| 1887 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; | 1897 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; |
| 1888 LocationSummary* summary = | 1898 LocationSummary* summary = |
| 1889 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1899 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1890 summary->set_in(0, Location::RequiresRegister()); | 1900 summary->set_in(0, Location::RequiresRegister()); |
| 1891 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); | 1901 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); |
| 1892 summary->set_out(Location::RequiresXmmRegister()); | 1902 summary->set_out(Location::RequiresXmmRegister()); |
| 1893 return summary; | 1903 return summary; |
| 1894 } | 1904 } |
| 1895 | 1905 |
| 1896 | 1906 |
| 1897 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1907 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1898 const intptr_t v_cid = value()->ResultCid(); | 1908 const intptr_t v_cid = value()->ResultCid(); |
| 1899 | 1909 |
| 1900 const Register value = locs()->in(0).reg(); | 1910 const Register value = locs()->in(0).reg(); |
| 1901 const XmmRegister result = locs()->out().xmm_reg(); | 1911 const XmmRegister result = locs()->out().xmm_reg(); |
| 1902 if (v_cid != kDoubleCid) { | 1912 if (v_cid != kDoubleCid) { |
| 1903 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); | 1913 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); |
| 1904 compiler->LoadDoubleOrSmiToXmm(result, | 1914 compiler->LoadDoubleOrSmiToXmm(result, |
| 1905 value, | 1915 value, |
| 1906 locs()->temp(0).reg(), | 1916 locs()->temp(0).reg(), |
| 1907 deopt); | 1917 deopt); |
| 1908 } else { | 1918 } else { |
| 1909 __ movsd(result, FieldAddress(value, Double::value_offset())); | 1919 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 1910 } | 1920 } |
| 1911 } | 1921 } |
| 1912 | 1922 |
| 1913 | 1923 |
| 1914 LocationSummary* UnboxedDoubleBinaryOpInstr::MakeLocationSummary() const { | 1924 LocationSummary* UnboxedDoubleBinaryOpComp::MakeLocationSummary() const { |
| 1915 const intptr_t kNumInputs = 2; | 1925 const intptr_t kNumInputs = 2; |
| 1916 const intptr_t kNumTemps = 0; | 1926 const intptr_t kNumTemps = 0; |
| 1917 LocationSummary* summary = | 1927 LocationSummary* summary = |
| 1918 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1928 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1919 summary->set_in(0, Location::RequiresXmmRegister()); | 1929 summary->set_in(0, Location::RequiresXmmRegister()); |
| 1920 summary->set_in(1, Location::RequiresXmmRegister()); | 1930 summary->set_in(1, Location::RequiresXmmRegister()); |
| 1921 summary->set_out(Location::SameAsFirstInput()); | 1931 summary->set_out(Location::SameAsFirstInput()); |
| 1922 return summary; | 1932 return summary; |
| 1923 } | 1933 } |
| 1924 | 1934 |
| 1925 | 1935 |
| 1926 void UnboxedDoubleBinaryOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1936 void UnboxedDoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1927 XmmRegister left = locs()->in(0).xmm_reg(); | 1937 XmmRegister left = locs()->in(0).xmm_reg(); |
| 1928 XmmRegister right = locs()->in(1).xmm_reg(); | 1938 XmmRegister right = locs()->in(1).xmm_reg(); |
| 1929 | 1939 |
| 1930 ASSERT(locs()->out().xmm_reg() == left); | 1940 ASSERT(locs()->out().xmm_reg() == left); |
| 1931 | 1941 |
| 1932 switch (op_kind()) { | 1942 switch (op_kind()) { |
| 1933 case Token::kADD: __ addsd(left, right); break; | 1943 case Token::kADD: __ addsd(left, right); break; |
| 1934 case Token::kSUB: __ subsd(left, right); break; | 1944 case Token::kSUB: __ subsd(left, right); break; |
| 1935 case Token::kMUL: __ mulsd(left, right); break; | 1945 case Token::kMUL: __ mulsd(left, right); break; |
| 1936 case Token::kDIV: __ divsd(left, right); break; | 1946 case Token::kDIV: __ divsd(left, right); break; |
| 1937 default: UNREACHABLE(); | 1947 default: UNREACHABLE(); |
| 1938 } | 1948 } |
| 1939 } | 1949 } |
| 1940 | 1950 |
| 1941 | 1951 |
| 1942 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 1952 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { |
| 1943 const intptr_t kNumInputs = 1; | 1953 const intptr_t kNumInputs = 1; |
| 1944 const intptr_t kNumTemps = 0; | 1954 const intptr_t kNumTemps = 0; |
| 1945 LocationSummary* summary = | 1955 LocationSummary* summary = |
| 1946 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1956 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1947 summary->set_in(0, Location::RequiresRegister()); | 1957 summary->set_in(0, Location::RequiresRegister()); |
| 1948 summary->set_out(Location::SameAsFirstInput()); | 1958 summary->set_out(Location::SameAsFirstInput()); |
| 1949 return summary; | 1959 return summary; |
| 1950 } | 1960 } |
| 1951 | 1961 |
| 1952 | 1962 |
| 1953 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1963 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1954 Register value = locs()->in(0).reg(); | 1964 Register value = locs()->in(0).reg(); |
| 1955 ASSERT(value == locs()->out().reg()); | 1965 ASSERT(value == locs()->out().reg()); |
| 1956 switch (op_kind()) { | 1966 switch (op_kind()) { |
| 1957 case Token::kNEGATE: { | 1967 case Token::kNEGATE: { |
| 1958 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 1968 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 1959 kDeoptUnaryOp); | 1969 kDeoptUnaryOp); |
| 1960 __ negl(value); | 1970 __ negl(value); |
| 1961 __ j(OVERFLOW, deopt); | 1971 __ j(OVERFLOW, deopt); |
| 1962 break; | 1972 break; |
| 1963 } | 1973 } |
| 1964 case Token::kBIT_NOT: | 1974 case Token::kBIT_NOT: |
| 1965 __ notl(value); | 1975 __ notl(value); |
| 1966 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. | 1976 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. |
| 1967 break; | 1977 break; |
| 1968 default: | 1978 default: |
| 1969 UNREACHABLE(); | 1979 UNREACHABLE(); |
| 1970 } | 1980 } |
| 1971 } | 1981 } |
| 1972 | 1982 |
| 1973 | 1983 |
| 1974 LocationSummary* NumberNegateInstr::MakeLocationSummary() const { | 1984 LocationSummary* NumberNegateComp::MakeLocationSummary() const { |
| 1975 const intptr_t kNumInputs = 1; | 1985 const intptr_t kNumInputs = 1; |
| 1976 const intptr_t kNumTemps = 1; // Needed for doubles. | 1986 const intptr_t kNumTemps = 1; // Needed for doubles. |
| 1977 LocationSummary* summary = | 1987 LocationSummary* summary = |
| 1978 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1988 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1979 summary->set_in(0, Location::RegisterLocation(EAX)); | 1989 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1980 summary->set_temp(0, Location::RegisterLocation(ECX)); | 1990 summary->set_temp(0, Location::RegisterLocation(ECX)); |
| 1981 summary->set_out(Location::RegisterLocation(EAX)); | 1991 summary->set_out(Location::RegisterLocation(EAX)); |
| 1982 return summary; | 1992 return summary; |
| 1983 } | 1993 } |
| 1984 | 1994 |
| 1985 | 1995 |
| 1986 void NumberNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1996 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1987 const ICData& ic_data = *instance_call()->ic_data(); | 1997 const ICData& ic_data = *instance_call()->ic_data(); |
| 1988 ASSERT(!ic_data.IsNull()); | 1998 ASSERT(!ic_data.IsNull()); |
| 1989 ASSERT(ic_data.num_args_tested() == 1); | 1999 ASSERT(ic_data.num_args_tested() == 1); |
| 1990 | 2000 |
| 1991 // TODO(srdjan): Implement for more checks. | 2001 // TODO(srdjan): Implement for more checks. |
| 1992 ASSERT(ic_data.NumberOfChecks() == 1); | 2002 ASSERT(ic_data.NumberOfChecks() == 1); |
| 1993 intptr_t test_class_id; | 2003 intptr_t test_class_id; |
| 1994 Function& target = Function::Handle(); | 2004 Function& target = Function::Handle(); |
| 1995 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); | 2005 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); |
| 1996 | 2006 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2022 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); | 2032 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); |
| 2023 __ DoubleNegate(XMM0); | 2033 __ DoubleNegate(XMM0); |
| 2024 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 2034 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 2025 } else { | 2035 } else { |
| 2026 UNREACHABLE(); | 2036 UNREACHABLE(); |
| 2027 } | 2037 } |
| 2028 ASSERT(ResultCid() == kDoubleCid); | 2038 ASSERT(ResultCid() == kDoubleCid); |
| 2029 } | 2039 } |
| 2030 | 2040 |
| 2031 | 2041 |
| 2032 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { | 2042 LocationSummary* DoubleToDoubleComp::MakeLocationSummary() const { |
| 2033 const intptr_t kNumInputs = 1; | 2043 const intptr_t kNumInputs = 1; |
| 2034 const intptr_t kNumTemps = 1; | 2044 const intptr_t kNumTemps = 1; |
| 2035 LocationSummary* locs = | 2045 LocationSummary* locs = |
| 2036 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2046 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2037 locs->set_in(0, Location::RequiresRegister()); | 2047 locs->set_in(0, Location::RequiresRegister()); |
| 2038 locs->set_temp(0, Location::RequiresRegister()); | 2048 locs->set_temp(0, Location::RequiresRegister()); |
| 2039 locs->set_out(Location::SameAsFirstInput()); | 2049 locs->set_out(Location::SameAsFirstInput()); |
| 2040 return locs; | 2050 return locs; |
| 2041 } | 2051 } |
| 2042 | 2052 |
| 2043 | 2053 |
| 2044 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2054 void DoubleToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2045 Register value = locs()->in(0).reg(); | 2055 Register value = locs()->in(0).reg(); |
| 2046 Register result = locs()->out().reg(); | 2056 Register result = locs()->out().reg(); |
| 2047 | 2057 |
| 2048 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2058 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 2049 kDeoptDoubleToDouble); | 2059 kDeoptDoubleToDouble); |
| 2050 Register temp = locs()->temp(0).reg(); | 2060 Register temp = locs()->temp(0).reg(); |
| 2051 __ testl(value, Immediate(kSmiTagMask)); | 2061 __ testl(value, Immediate(kSmiTagMask)); |
| 2052 __ j(ZERO, deopt); // Deoptimize if Smi. | 2062 __ j(ZERO, deopt); // Deoptimize if Smi. |
| 2053 __ CompareClassId(value, kDoubleCid, temp); | 2063 __ CompareClassId(value, kDoubleCid, temp); |
| 2054 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. | 2064 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. |
| 2055 ASSERT(value == result); | 2065 ASSERT(value == result); |
| 2056 } | 2066 } |
| 2057 | 2067 |
| 2058 | 2068 |
| 2059 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { | 2069 LocationSummary* SmiToDoubleComp::MakeLocationSummary() const { |
| 2060 return MakeCallSummary(); // Calls a stub to allocate result. | 2070 return MakeCallSummary(); // Calls a stub to allocate result. |
| 2061 } | 2071 } |
| 2062 | 2072 |
| 2063 | 2073 |
| 2064 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2074 void SmiToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2065 Register result = locs()->out().reg(); | 2075 Register result = locs()->out().reg(); |
| 2066 | 2076 |
| 2067 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2077 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 2068 kDeoptIntegerToDouble); | 2078 kDeoptIntegerToDouble); |
| 2069 | 2079 |
| 2070 const Class& double_class = compiler->double_class(); | 2080 const Class& double_class = compiler->double_class(); |
| 2071 const Code& stub = | 2081 const Code& stub = |
| 2072 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 2082 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 2073 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 2083 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 2074 | 2084 |
| 2075 // TODO(vegorov): allocate box in the driver loop to avoid spilling. | 2085 // TODO(vegorov): allocate box in the driver loop to avoid spilling. |
| 2076 compiler->GenerateCall(instance_call()->token_pos(), | 2086 compiler->GenerateCall(instance_call()->token_pos(), |
| 2077 &label, | 2087 &label, |
| 2078 PcDescriptors::kOther, | 2088 PcDescriptors::kOther, |
| 2079 locs()); | 2089 locs()); |
| 2080 ASSERT(result == EAX); | 2090 ASSERT(result == EAX); |
| 2081 Register value = EBX; | 2091 Register value = EBX; |
| 2082 // Preserve argument on the stack until after the deoptimization point. | 2092 // Preserve argument on the stack until after the deoptimization point. |
| 2083 __ movl(value, Address(ESP, 0)); | 2093 __ movl(value, Address(ESP, 0)); |
| 2084 | 2094 |
| 2085 __ testl(value, Immediate(kSmiTagMask)); | 2095 __ testl(value, Immediate(kSmiTagMask)); |
| 2086 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. | 2096 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. |
| 2087 __ SmiUntag(value); | 2097 __ SmiUntag(value); |
| 2088 __ cvtsi2sd(XMM0, value); | 2098 __ cvtsi2sd(XMM0, value); |
| 2089 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 2099 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 2090 __ Drop(1); | 2100 __ Drop(1); |
| 2091 } | 2101 } |
| 2092 | 2102 |
| 2093 | 2103 |
| 2094 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 2104 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { |
| 2095 return MakeCallSummary(); | 2105 return MakeCallSummary(); |
| 2096 } | 2106 } |
| 2097 | 2107 |
| 2098 | 2108 |
| 2099 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2109 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2100 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2110 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 2101 kDeoptPolymorphicInstanceCallTestFail); | 2111 kDeoptPolymorphicInstanceCallTestFail); |
| 2102 if (ic_data().NumberOfChecks() == 0) { | 2112 if (ic_data().NumberOfChecks() == 0) { |
| 2103 __ jmp(deopt); | 2113 __ jmp(deopt); |
| 2104 return; | 2114 return; |
| 2105 } | 2115 } |
| 2106 ASSERT(ic_data().num_args_tested() == 1); | 2116 ASSERT(ic_data().num_args_tested() == 1); |
| 2107 if (!with_checks()) { | 2117 if (!with_checks()) { |
| 2108 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | 2118 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
| 2109 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 2119 compiler->GenerateStaticCall(instance_call()->deopt_id(), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2130 EDI, // Class id register. | 2140 EDI, // Class id register. |
| 2131 instance_call()->ArgumentCount(), | 2141 instance_call()->ArgumentCount(), |
| 2132 instance_call()->argument_names(), | 2142 instance_call()->argument_names(), |
| 2133 deopt, | 2143 deopt, |
| 2134 instance_call()->deopt_id(), | 2144 instance_call()->deopt_id(), |
| 2135 instance_call()->token_pos(), | 2145 instance_call()->token_pos(), |
| 2136 locs()); | 2146 locs()); |
| 2137 } | 2147 } |
| 2138 | 2148 |
| 2139 | 2149 |
| 2140 LocationSummary* BranchInstr::MakeLocationSummary() const { | |
| 2141 UNREACHABLE(); | |
| 2142 return NULL; | |
| 2143 } | |
| 2144 | |
| 2145 | |
| 2146 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2150 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2147 comparison()->EmitBranchCode(compiler, this); | 2151 computation()->EmitBranchCode(compiler, this); |
| 2148 } | 2152 } |
| 2149 | 2153 |
| 2150 | 2154 |
| 2151 LocationSummary* CheckClassInstr::MakeLocationSummary() const { | 2155 LocationSummary* CheckClassComp::MakeLocationSummary() const { |
| 2152 const intptr_t kNumInputs = 1; | 2156 const intptr_t kNumInputs = 1; |
| 2153 const intptr_t kNumTemps = 1; | 2157 const intptr_t kNumTemps = 1; |
| 2154 LocationSummary* summary = | 2158 LocationSummary* summary = |
| 2155 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2159 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2156 summary->set_in(0, Location::RequiresRegister()); | 2160 summary->set_in(0, Location::RequiresRegister()); |
| 2157 summary->set_temp(0, Location::RequiresRegister()); | 2161 summary->set_temp(0, Location::RequiresRegister()); |
| 2158 return summary; | 2162 return summary; |
| 2159 } | 2163 } |
| 2160 | 2164 |
| 2161 | 2165 |
| 2162 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2166 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2163 Register value = locs()->in(0).reg(); | 2167 Register value = locs()->in(0).reg(); |
| 2164 Register temp = locs()->temp(0).reg(); | 2168 Register temp = locs()->temp(0).reg(); |
| 2165 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2169 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 2166 kDeoptCheckClass); | 2170 kDeoptCheckClass); |
| 2167 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid); | 2171 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid); |
| 2168 __ testl(value, Immediate(kSmiTagMask)); | 2172 __ testl(value, Immediate(kSmiTagMask)); |
| 2169 __ j(ZERO, deopt); | 2173 __ j(ZERO, deopt); |
| 2170 __ LoadClassId(temp, value); | 2174 __ LoadClassId(temp, value); |
| 2171 Label is_ok; | 2175 Label is_ok; |
| 2172 const intptr_t num_checks = unary_checks().NumberOfChecks(); | 2176 const intptr_t num_checks = unary_checks().NumberOfChecks(); |
| 2173 const bool use_near_jump = num_checks < 5; | 2177 const bool use_near_jump = num_checks < 5; |
| 2174 for (intptr_t i = 0; i < num_checks; i++) { | 2178 for (intptr_t i = 0; i < num_checks; i++) { |
| 2175 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); | 2179 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); |
| 2176 if (i == (num_checks - 1)) { | 2180 if (i == (num_checks - 1)) { |
| 2177 __ j(NOT_EQUAL, deopt); | 2181 __ j(NOT_EQUAL, deopt); |
| 2178 } else { | 2182 } else { |
| 2179 if (use_near_jump) { | 2183 if (use_near_jump) { |
| 2180 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 2184 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| 2181 } else { | 2185 } else { |
| 2182 __ j(EQUAL, &is_ok); | 2186 __ j(EQUAL, &is_ok); |
| 2183 } | 2187 } |
| 2184 } | 2188 } |
| 2185 } | 2189 } |
| 2186 __ Bind(&is_ok); | 2190 __ Bind(&is_ok); |
| 2187 } | 2191 } |
| 2188 | 2192 |
| 2189 | 2193 |
| 2190 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { | 2194 LocationSummary* CheckSmiComp::MakeLocationSummary() const { |
| 2191 const intptr_t kNumInputs = 1; | 2195 const intptr_t kNumInputs = 1; |
| 2192 const intptr_t kNumTemps = 0; | 2196 const intptr_t kNumTemps = 0; |
| 2193 LocationSummary* summary = | 2197 LocationSummary* summary = |
| 2194 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2198 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2195 summary->set_in(0, Location::RequiresRegister()); | 2199 summary->set_in(0, Location::RequiresRegister()); |
| 2196 return summary; | 2200 return summary; |
| 2197 } | 2201 } |
| 2198 | 2202 |
| 2199 | 2203 |
| 2200 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2204 void CheckSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2201 Register value = locs()->in(0).reg(); | 2205 Register value = locs()->in(0).reg(); |
| 2202 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2206 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 2203 kDeoptCheckSmi); | 2207 kDeoptCheckSmi); |
| 2204 __ testl(value, Immediate(kSmiTagMask)); | 2208 __ testl(value, Immediate(kSmiTagMask)); |
| 2205 __ j(NOT_ZERO, deopt); | 2209 __ j(NOT_ZERO, deopt); |
| 2206 } | 2210 } |
| 2207 | 2211 |
| 2208 | 2212 |
| 2209 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { | 2213 LocationSummary* CheckArrayBoundComp::MakeLocationSummary() const { |
| 2210 const intptr_t kNumInputs = 2; | 2214 const intptr_t kNumInputs = 2; |
| 2211 const intptr_t kNumTemps = 0; | 2215 const intptr_t kNumTemps = 0; |
| 2212 LocationSummary* locs = | 2216 LocationSummary* locs = |
| 2213 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2217 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2214 locs->set_in(0, Location::RequiresRegister()); | 2218 locs->set_in(0, Location::RequiresRegister()); |
| 2215 locs->set_in(1, Location::RegisterOrConstant(index())); | 2219 locs->set_in(1, Location::RegisterOrConstant(index())); |
| 2216 return locs; | 2220 return locs; |
| 2217 } | 2221 } |
| 2218 | 2222 |
| 2219 | 2223 |
| 2220 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2224 void CheckArrayBoundComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2221 Register receiver = locs()->in(0).reg(); | 2225 Register receiver = locs()->in(0).reg(); |
| 2222 | 2226 |
| 2223 const DeoptReasonId deopt_reason = | 2227 const DeoptReasonId deopt_reason = |
| 2224 (array_type() == kGrowableObjectArrayCid) ? | 2228 (array_type() == kGrowableObjectArrayCid) ? |
| 2225 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; | 2229 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; |
| 2226 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2230 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 2227 deopt_reason); | 2231 deopt_reason); |
| 2228 ASSERT(array_type() == kArrayCid || | 2232 ASSERT(array_type() == kArrayCid || |
| 2229 array_type() == kImmutableArrayCid || | 2233 array_type() == kImmutableArrayCid || |
| 2230 array_type() == kGrowableObjectArrayCid); | 2234 array_type() == kGrowableObjectArrayCid); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2245 __ j(ABOVE_EQUAL, deopt); | 2249 __ j(ABOVE_EQUAL, deopt); |
| 2246 } | 2250 } |
| 2247 } | 2251 } |
| 2248 | 2252 |
| 2249 | 2253 |
| 2250 } // namespace dart | 2254 } // namespace dart |
| 2251 | 2255 |
| 2252 #undef __ | 2256 #undef __ |
| 2253 | 2257 |
| 2254 #endif // defined TARGET_ARCH_X64 | 2258 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |