| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| 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 RAX. | 26 // on the stack and return the result in a fixed register RAX. |
| 27 LocationSummary* Computation::MakeCallSummary() { | 27 LocationSummary* Instruction::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(RAX)); | 29 result->set_out(Location::RegisterLocation(RAX)); |
| 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 __ pushq(locs()->out().reg()); | |
| 38 } | |
| 39 } | |
| 40 | |
| 41 | |
| 42 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 34 LocationSummary* ReturnInstr::MakeLocationSummary() const { |
| 43 const intptr_t kNumInputs = 1; | 35 const intptr_t kNumInputs = 1; |
| 44 const intptr_t kNumTemps = 1; | 36 const intptr_t kNumTemps = 1; |
| 45 LocationSummary* locs = | 37 LocationSummary* locs = |
| 46 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 38 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 47 locs->set_in(0, Location::RegisterLocation(RAX)); | 39 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 48 locs->set_temp(0, Location::RequiresRegister()); | 40 locs->set_temp(0, Location::RequiresRegister()); |
| 49 return locs; | 41 return locs; |
| 50 } | 42 } |
| 51 | 43 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 __ nop(1); | 112 __ nop(1); |
| 121 __ nop(1); | 113 __ nop(1); |
| 122 __ nop(1); | 114 __ nop(1); |
| 123 __ nop(1); | 115 __ nop(1); |
| 124 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, | 116 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
| 125 deopt_id(), | 117 deopt_id(), |
| 126 token_pos()); | 118 token_pos()); |
| 127 } | 119 } |
| 128 | 120 |
| 129 | 121 |
| 130 LocationSummary* ClosureCallComp::MakeLocationSummary() const { | 122 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { |
| 131 const intptr_t kNumInputs = 0; | 123 const intptr_t kNumInputs = 0; |
| 132 const intptr_t kNumTemps = 1; | 124 const intptr_t kNumTemps = 1; |
| 133 LocationSummary* result = | 125 LocationSummary* result = |
| 134 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 126 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 135 result->set_out(Location::RegisterLocation(RAX)); | 127 result->set_out(Location::RegisterLocation(RAX)); |
| 136 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. | 128 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. |
| 137 return result; | 129 return result; |
| 138 } | 130 } |
| 139 | 131 |
| 140 | 132 |
| 141 LocationSummary* LoadLocalComp::MakeLocationSummary() const { | 133 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { |
| 142 return LocationSummary::Make(0, | 134 return LocationSummary::Make(0, |
| 143 Location::RequiresRegister(), | 135 Location::RequiresRegister(), |
| 144 LocationSummary::kNoCall); | 136 LocationSummary::kNoCall); |
| 145 } | 137 } |
| 146 | 138 |
| 147 | 139 |
| 148 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 140 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 149 Register result = locs()->out().reg(); | 141 Register result = locs()->out().reg(); |
| 150 __ movq(result, Address(RBP, local().index() * kWordSize)); | 142 __ movq(result, Address(RBP, local().index() * kWordSize)); |
| 151 } | 143 } |
| 152 | 144 |
| 153 | 145 |
| 154 LocationSummary* StoreLocalComp::MakeLocationSummary() const { | 146 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { |
| 155 return LocationSummary::Make(1, | 147 return LocationSummary::Make(1, |
| 156 Location::SameAsFirstInput(), | 148 Location::SameAsFirstInput(), |
| 157 LocationSummary::kNoCall); | 149 LocationSummary::kNoCall); |
| 158 } | 150 } |
| 159 | 151 |
| 160 | 152 |
| 161 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 153 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 162 Register value = locs()->in(0).reg(); | 154 Register value = locs()->in(0).reg(); |
| 163 Register result = locs()->out().reg(); | 155 Register result = locs()->out().reg(); |
| 164 ASSERT(result == value); // Assert that register assignment is correct. | 156 ASSERT(result == value); // Assert that register assignment is correct. |
| 165 __ movq(Address(RBP, local().index() * kWordSize), value); | 157 __ movq(Address(RBP, local().index() * kWordSize), value); |
| 166 } | 158 } |
| 167 | 159 |
| 168 | 160 |
| 169 LocationSummary* ConstantComp::MakeLocationSummary() const { | 161 LocationSummary* ConstantInstr::MakeLocationSummary() const { |
| 170 return LocationSummary::Make(0, | 162 return LocationSummary::Make(0, |
| 171 Location::RequiresRegister(), | 163 Location::RequiresRegister(), |
| 172 LocationSummary::kNoCall); | 164 LocationSummary::kNoCall); |
| 173 } | 165 } |
| 174 | 166 |
| 175 | 167 |
| 176 void ConstantComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 168 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 177 // Register allocator drops constant definitions that have no uses. | 169 // The register allocator drops constant definitions that have no uses. |
| 178 if (!locs()->out().IsInvalid()) { | 170 if (!locs()->out().IsInvalid()) { |
| 179 Register result = locs()->out().reg(); | 171 Register result = locs()->out().reg(); |
| 180 __ LoadObject(result, value()); | 172 __ LoadObject(result, value()); |
| 181 } | 173 } |
| 182 } | 174 } |
| 183 | 175 |
| 184 | 176 |
| 185 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { | 177 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { |
| 186 const intptr_t kNumInputs = 3; | 178 const intptr_t kNumInputs = 3; |
| 187 const intptr_t kNumTemps = 0; | 179 const intptr_t kNumTemps = 0; |
| 188 LocationSummary* summary = | 180 LocationSummary* summary = |
| 189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 181 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 190 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. | 182 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. |
| 191 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. | 183 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. |
| 192 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. | 184 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. |
| 193 summary->set_out(Location::RegisterLocation(RAX)); | 185 summary->set_out(Location::RegisterLocation(RAX)); |
| 194 return summary; | 186 return summary; |
| 195 } | 187 } |
| 196 | 188 |
| 197 | 189 |
| 198 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { | 190 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { |
| 199 const intptr_t kNumInputs = 1; | 191 const intptr_t kNumInputs = 1; |
| 200 const intptr_t kNumTemps = 0; | 192 const intptr_t kNumTemps = 0; |
| 201 LocationSummary* locs = | 193 LocationSummary* locs = |
| 202 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 194 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 203 locs->set_in(0, Location::RegisterLocation(RAX)); | 195 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 204 locs->set_out(Location::RegisterLocation(RAX)); | 196 locs->set_out(Location::RegisterLocation(RAX)); |
| 205 return locs; | 197 return locs; |
| 206 } | 198 } |
| 207 | 199 |
| 208 | 200 |
| 209 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 201 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 210 Register obj = locs()->in(0).reg(); | 202 Register obj = locs()->in(0).reg(); |
| 211 Register result = locs()->out().reg(); | 203 Register result = locs()->out().reg(); |
| 212 | 204 |
| 213 if (!is_eliminated()) { | 205 if (!is_eliminated()) { |
| 214 // Check that the type of the value is allowed in conditional context. | 206 // Check that the type of the value is allowed in conditional context. |
| 215 // Call the runtime if the object is not bool::true or bool::false. | 207 // Call the runtime if the object is not bool::true or bool::false. |
| 216 Label done; | 208 Label done; |
| 217 __ CompareObject(obj, compiler->bool_true()); | 209 __ CompareObject(obj, compiler->bool_true()); |
| 218 __ j(EQUAL, &done, Assembler::kNearJump); | 210 __ j(EQUAL, &done, Assembler::kNearJump); |
| 219 __ CompareObject(obj, compiler->bool_false()); | 211 __ CompareObject(obj, compiler->bool_false()); |
| 220 __ j(EQUAL, &done, Assembler::kNearJump); | 212 __ j(EQUAL, &done, Assembler::kNearJump); |
| 221 | 213 |
| 222 __ pushq(obj); // Push the source object. | 214 __ pushq(obj); // Push the source object. |
| 223 compiler->GenerateCallRuntime(token_pos(), | 215 compiler->GenerateCallRuntime(token_pos(), |
| 224 kConditionTypeErrorRuntimeEntry, | 216 kConditionTypeErrorRuntimeEntry, |
| 225 locs()); | 217 locs()); |
| 226 // We should never return here. | 218 // We should never return here. |
| 227 __ int3(); | 219 __ int3(); |
| 228 __ Bind(&done); | 220 __ Bind(&done); |
| 229 } | 221 } |
| 230 ASSERT(obj == result); | 222 ASSERT(obj == result); |
| 231 } | 223 } |
| 232 | 224 |
| 233 | 225 |
| 234 LocationSummary* ArgumentDefinitionTestComp::MakeLocationSummary() const { | 226 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const { |
| 235 const intptr_t kNumInputs = 1; | 227 const intptr_t kNumInputs = 1; |
| 236 const intptr_t kNumTemps = 0; | 228 const intptr_t kNumTemps = 0; |
| 237 LocationSummary* locs = | 229 LocationSummary* locs = |
| 238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 230 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 239 locs->set_in(0, Location::RegisterLocation(RAX)); | 231 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 240 locs->set_out(Location::RegisterLocation(RAX)); | 232 locs->set_out(Location::RegisterLocation(RAX)); |
| 241 return locs; | 233 return locs; |
| 242 } | 234 } |
| 243 | 235 |
| 244 | 236 |
| 245 void ArgumentDefinitionTestComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 237 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 246 Register saved_args_desc = locs()->in(0).reg(); | 238 Register saved_args_desc = locs()->in(0).reg(); |
| 247 Register result = locs()->out().reg(); | 239 Register result = locs()->out().reg(); |
| 248 | 240 |
| 249 // Push the result place holder initialized to NULL. | 241 // Push the result place holder initialized to NULL. |
| 250 __ PushObject(Object::ZoneHandle()); | 242 __ PushObject(Object::ZoneHandle()); |
| 251 __ pushq(Immediate(Smi::RawValue(formal_parameter_index()))); | 243 __ pushq(Immediate(Smi::RawValue(formal_parameter_index()))); |
| 252 __ PushObject(formal_parameter_name()); | 244 __ PushObject(formal_parameter_name()); |
| 253 __ pushq(saved_args_desc); | 245 __ pushq(saved_args_desc); |
| 254 compiler->GenerateCallRuntime(token_pos(), | 246 compiler->GenerateCallRuntime(token_pos(), |
| 255 kArgumentDefinitionTestRuntimeEntry, | 247 kArgumentDefinitionTestRuntimeEntry, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 267 case Token::kGT: return GREATER; | 259 case Token::kGT: return GREATER; |
| 268 case Token::kLTE: return LESS_EQUAL; | 260 case Token::kLTE: return LESS_EQUAL; |
| 269 case Token::kGTE: return GREATER_EQUAL; | 261 case Token::kGTE: return GREATER_EQUAL; |
| 270 default: | 262 default: |
| 271 UNREACHABLE(); | 263 UNREACHABLE(); |
| 272 return OVERFLOW; | 264 return OVERFLOW; |
| 273 } | 265 } |
| 274 } | 266 } |
| 275 | 267 |
| 276 | 268 |
| 277 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { | 269 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { |
| 278 const intptr_t kNumInputs = 2; | 270 const intptr_t kNumInputs = 2; |
| 279 const bool is_checked_strict_equal = | 271 const bool is_checked_strict_equal = |
| 280 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); | 272 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); |
| 281 if (receiver_class_id() == kDoubleCid) { | 273 if (receiver_class_id() == kDoubleCid) { |
| 282 const intptr_t kNumTemps = 0; | 274 const intptr_t kNumTemps = 0; |
| 283 LocationSummary* locs = | 275 LocationSummary* locs = |
| 284 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 276 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 285 locs->set_in(0, Location::RequiresXmmRegister()); | 277 locs->set_in(0, Location::RequiresXmmRegister()); |
| 286 locs->set_in(1, Location::RequiresXmmRegister()); | 278 locs->set_in(1, Location::RequiresXmmRegister()); |
| 287 locs->set_out(Location::RequiresRegister()); | 279 locs->set_out(Location::RequiresRegister()); |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 if (branch != NULL) { | 612 if (branch != NULL) { |
| 621 compiler->EmitDoubleCompareBranch( | 613 compiler->EmitDoubleCompareBranch( |
| 622 true_condition, left, right, branch); | 614 true_condition, left, right, branch); |
| 623 } else { | 615 } else { |
| 624 compiler->EmitDoubleCompareBool( | 616 compiler->EmitDoubleCompareBool( |
| 625 true_condition, left, right, locs.out().reg()); | 617 true_condition, left, right, locs.out().reg()); |
| 626 } | 618 } |
| 627 } | 619 } |
| 628 | 620 |
| 629 | 621 |
| 630 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 622 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 631 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); | 623 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); |
| 632 BranchInstr* kNoBranch = NULL; | 624 BranchInstr* kNoBranch = NULL; |
| 633 if (receiver_class_id() == kSmiCid) { | 625 if (receiver_class_id() == kSmiCid) { |
| 634 // Deoptimizes if both arguments not Smi. | 626 // Deoptimizes if both arguments not Smi. |
| 635 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); | 627 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| 636 return; | 628 return; |
| 637 } | 629 } |
| 638 if (receiver_class_id() == kDoubleCid) { | 630 if (receiver_class_id() == kDoubleCid) { |
| 639 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. | 631 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. |
| 640 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); | 632 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 658 __ pushq(right); | 650 __ pushq(right); |
| 659 EmitEqualityAsInstanceCall(compiler, | 651 EmitEqualityAsInstanceCall(compiler, |
| 660 deopt_id(), | 652 deopt_id(), |
| 661 token_pos(), | 653 token_pos(), |
| 662 kind(), | 654 kind(), |
| 663 locs()); | 655 locs()); |
| 664 ASSERT(locs()->out().reg() == RAX); | 656 ASSERT(locs()->out().reg() == RAX); |
| 665 } | 657 } |
| 666 | 658 |
| 667 | 659 |
| 668 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler, | 660 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 669 BranchInstr* branch) { | 661 BranchInstr* branch) { |
| 670 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 662 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 671 if (receiver_class_id() == kSmiCid) { | 663 if (receiver_class_id() == kSmiCid) { |
| 672 // Deoptimizes if both arguments not Smi. | 664 // Deoptimizes if both arguments not Smi. |
| 673 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 665 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 674 return; | 666 return; |
| 675 } | 667 } |
| 676 if (receiver_class_id() == kDoubleCid) { | 668 if (receiver_class_id() == kDoubleCid) { |
| 677 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. | 669 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. |
| 678 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 670 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 679 return; | 671 return; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 698 deopt_id(), | 690 deopt_id(), |
| 699 token_pos(), | 691 token_pos(), |
| 700 Token::kEQ, // kNE reverse occurs at branch. | 692 Token::kEQ, // kNE reverse occurs at branch. |
| 701 locs()); | 693 locs()); |
| 702 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; | 694 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; |
| 703 __ CompareObject(RAX, compiler->bool_true()); | 695 __ CompareObject(RAX, compiler->bool_true()); |
| 704 branch->EmitBranchOnCondition(compiler, branch_condition); | 696 branch->EmitBranchOnCondition(compiler, branch_condition); |
| 705 } | 697 } |
| 706 | 698 |
| 707 | 699 |
| 708 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | 700 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { |
| 709 const intptr_t kNumInputs = 2; | 701 const intptr_t kNumInputs = 2; |
| 710 if (operands_class_id() == kDoubleCid) { | 702 if (operands_class_id() == kDoubleCid) { |
| 711 const intptr_t kNumTemps = 0; | 703 const intptr_t kNumTemps = 0; |
| 712 LocationSummary* summary = | 704 LocationSummary* summary = |
| 713 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 705 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 714 summary->set_in(0, Location::RequiresXmmRegister()); | 706 summary->set_in(0, Location::RequiresXmmRegister()); |
| 715 summary->set_in(1, Location::RequiresXmmRegister()); | 707 summary->set_in(1, Location::RequiresXmmRegister()); |
| 716 summary->set_out(Location::RequiresRegister()); | 708 summary->set_out(Location::RequiresRegister()); |
| 717 return summary; | 709 return summary; |
| 718 } else if (operands_class_id() == kSmiCid) { | 710 } else if (operands_class_id() == kSmiCid) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 729 LocationSummary* locs = | 721 LocationSummary* locs = |
| 730 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 722 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 731 // Pick arbitrary fixed input registers because this is a call. | 723 // Pick arbitrary fixed input registers because this is a call. |
| 732 locs->set_in(0, Location::RegisterLocation(RAX)); | 724 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 733 locs->set_in(1, Location::RegisterLocation(RCX)); | 725 locs->set_in(1, Location::RegisterLocation(RCX)); |
| 734 locs->set_out(Location::RegisterLocation(RAX)); | 726 locs->set_out(Location::RegisterLocation(RAX)); |
| 735 return locs; | 727 return locs; |
| 736 } | 728 } |
| 737 | 729 |
| 738 | 730 |
| 739 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 731 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 740 if (operands_class_id() == kSmiCid) { | 732 if (operands_class_id() == kSmiCid) { |
| 741 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); | 733 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); |
| 742 return; | 734 return; |
| 743 } | 735 } |
| 744 if (operands_class_id() == kDoubleCid) { | 736 if (operands_class_id() == kDoubleCid) { |
| 745 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); | 737 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); |
| 746 return; | 738 return; |
| 747 } | 739 } |
| 748 | 740 |
| 749 // Push arguments for the call. | 741 // Push arguments for the call. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 compiler->GenerateInstanceCall(deopt_id(), | 778 compiler->GenerateInstanceCall(deopt_id(), |
| 787 token_pos(), | 779 token_pos(), |
| 788 function_name, | 780 function_name, |
| 789 kNumArguments, | 781 kNumArguments, |
| 790 Array::ZoneHandle(), // No optional arguments. | 782 Array::ZoneHandle(), // No optional arguments. |
| 791 kNumArgsChecked, | 783 kNumArgsChecked, |
| 792 locs()); | 784 locs()); |
| 793 } | 785 } |
| 794 | 786 |
| 795 | 787 |
| 796 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler, | 788 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 797 BranchInstr* branch) { | 789 BranchInstr* branch) { |
| 798 if (operands_class_id() == kSmiCid) { | 790 if (operands_class_id() == kSmiCid) { |
| 799 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 791 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 800 return; | 792 return; |
| 801 } | 793 } |
| 802 if (operands_class_id() == kDoubleCid) { | 794 if (operands_class_id() == kDoubleCid) { |
| 803 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 795 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 804 return; | 796 return; |
| 805 } | 797 } |
| 806 EmitNativeCode(compiler); | 798 EmitNativeCode(compiler); |
| 807 __ CompareObject(RAX, compiler->bool_true()); | 799 __ CompareObject(RAX, compiler->bool_true()); |
| 808 branch->EmitBranchOnCondition(compiler, EQUAL); | 800 branch->EmitBranchOnCondition(compiler, EQUAL); |
| 809 } | 801 } |
| 810 | 802 |
| 811 | 803 |
| 812 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 804 LocationSummary* NativeCallInstr::MakeLocationSummary() const { |
| 813 const intptr_t kNumInputs = 0; | 805 const intptr_t kNumInputs = 0; |
| 814 const intptr_t kNumTemps = 3; | 806 const intptr_t kNumTemps = 3; |
| 815 LocationSummary* locs = | 807 LocationSummary* locs = |
| 816 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 808 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 817 locs->set_temp(0, Location::RegisterLocation(RAX)); | 809 locs->set_temp(0, Location::RegisterLocation(RAX)); |
| 818 locs->set_temp(1, Location::RegisterLocation(RBX)); | 810 locs->set_temp(1, Location::RegisterLocation(RBX)); |
| 819 locs->set_temp(2, Location::RegisterLocation(R10)); | 811 locs->set_temp(2, Location::RegisterLocation(R10)); |
| 820 locs->set_out(Location::RegisterLocation(RAX)); | 812 locs->set_out(Location::RegisterLocation(RAX)); |
| 821 return locs; | 813 return locs; |
| 822 } | 814 } |
| 823 | 815 |
| 824 | 816 |
| 825 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 817 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 826 ASSERT(locs()->temp(0).reg() == RAX); | 818 ASSERT(locs()->temp(0).reg() == RAX); |
| 827 ASSERT(locs()->temp(1).reg() == RBX); | 819 ASSERT(locs()->temp(1).reg() == RBX); |
| 828 ASSERT(locs()->temp(2).reg() == R10); | 820 ASSERT(locs()->temp(2).reg() == R10); |
| 829 Register result = locs()->out().reg(); | 821 Register result = locs()->out().reg(); |
| 830 | 822 |
| 831 // Push the result place holder initialized to NULL. | 823 // Push the result place holder initialized to NULL. |
| 832 __ PushObject(Object::ZoneHandle()); | 824 __ PushObject(Object::ZoneHandle()); |
| 833 // Pass a pointer to the first argument in RAX. | 825 // Pass a pointer to the first argument in RAX. |
| 834 intptr_t arg_count = argument_count(); | 826 intptr_t arg_count = argument_count(); |
| 835 if (is_native_instance_closure()) { | 827 if (is_native_instance_closure()) { |
| 836 arg_count += 1; | 828 arg_count += 1; |
| 837 } | 829 } |
| 838 if (!has_optional_parameters() && !is_native_instance_closure()) { | 830 if (!has_optional_parameters() && !is_native_instance_closure()) { |
| 839 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize)); | 831 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize)); |
| 840 } else { | 832 } else { |
| 841 __ leaq(RAX, | 833 __ leaq(RAX, |
| 842 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | 834 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
| 843 } | 835 } |
| 844 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 836 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
| 845 __ movq(R10, Immediate(arg_count)); | 837 __ movq(R10, Immediate(arg_count)); |
| 846 compiler->GenerateCall(token_pos(), | 838 compiler->GenerateCall(token_pos(), |
| 847 &StubCode::CallNativeCFunctionLabel(), | 839 &StubCode::CallNativeCFunctionLabel(), |
| 848 PcDescriptors::kOther, | 840 PcDescriptors::kOther, |
| 849 locs()); | 841 locs()); |
| 850 __ popq(result); | 842 __ popq(result); |
| 851 } | 843 } |
| 852 | 844 |
| 853 | 845 |
| 854 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { | 846 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 855 const intptr_t kNumInputs = 2; | 847 const intptr_t kNumInputs = 2; |
| 856 if (receiver_type() == kGrowableObjectArrayCid) { | 848 if (receiver_type() == kGrowableObjectArrayCid) { |
| 857 const intptr_t kNumTemps = 1; | 849 const intptr_t kNumTemps = 1; |
| 858 LocationSummary* locs = | 850 LocationSummary* locs = |
| 859 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 851 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 860 locs->set_in(0, Location::RequiresRegister()); | 852 locs->set_in(0, Location::RequiresRegister()); |
| 861 locs->set_in(1, Location::RequiresRegister()); | 853 locs->set_in(1, Location::RequiresRegister()); |
| 862 locs->set_temp(0, Location::RequiresRegister()); | 854 locs->set_temp(0, Location::RequiresRegister()); |
| 863 locs->set_out(Location::RequiresRegister()); | 855 locs->set_out(Location::RequiresRegister()); |
| 864 return locs; | 856 return locs; |
| 865 } else { | 857 } else { |
| 866 ASSERT((receiver_type() == kArrayCid) || | 858 ASSERT((receiver_type() == kArrayCid) || |
| 867 (receiver_type() == kImmutableArrayCid)); | 859 (receiver_type() == kImmutableArrayCid)); |
| 868 return LocationSummary::Make(kNumInputs, | 860 return LocationSummary::Make(kNumInputs, |
| 869 Location::RequiresRegister(), | 861 Location::RequiresRegister(), |
| 870 LocationSummary::kNoCall); | 862 LocationSummary::kNoCall); |
| 871 } | 863 } |
| 872 } | 864 } |
| 873 | 865 |
| 874 | 866 |
| 875 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 867 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 876 Register receiver = locs()->in(0).reg(); | 868 Register receiver = locs()->in(0).reg(); |
| 877 Register index = locs()->in(1).reg(); | 869 Register index = locs()->in(1).reg(); |
| 878 Register result = locs()->out().reg(); | 870 Register result = locs()->out().reg(); |
| 879 | 871 |
| 880 switch (receiver_type()) { | 872 switch (receiver_type()) { |
| 881 case kArrayCid: | 873 case kArrayCid: |
| 882 case kImmutableArrayCid: | 874 case kImmutableArrayCid: |
| 883 // Note that index is Smi, i.e, times 4. | 875 // Note that index is Smi, i.e, times 4. |
| 884 ASSERT(kSmiTagShift == 1); | 876 ASSERT(kSmiTagShift == 1); |
| 885 __ movq(result, FieldAddress(receiver, index, TIMES_4, sizeof(RawArray))); | 877 __ movq(result, FieldAddress(receiver, index, TIMES_4, sizeof(RawArray))); |
| 886 break; | 878 break; |
| 887 | 879 |
| 888 case kGrowableObjectArrayCid: { | 880 case kGrowableObjectArrayCid: { |
| 889 Register temp = locs()->temp(0).reg(); | 881 Register temp = locs()->temp(0).reg(); |
| 890 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); | 882 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); |
| 891 // Note that index is Smi, i.e, times 4. | 883 // Note that index is Smi, i.e, times 4. |
| 892 ASSERT(kSmiTagShift == 1); | 884 ASSERT(kSmiTagShift == 1); |
| 893 __ movq(result, FieldAddress(temp, index, TIMES_4, sizeof(RawArray))); | 885 __ movq(result, FieldAddress(temp, index, TIMES_4, sizeof(RawArray))); |
| 894 break; | 886 break; |
| 895 } | 887 } |
| 896 | 888 |
| 897 default: | 889 default: |
| 898 UNREACHABLE(); | 890 UNREACHABLE(); |
| 899 break; | 891 break; |
| 900 } | 892 } |
| 901 } | 893 } |
| 902 | 894 |
| 903 | 895 |
| 904 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { | 896 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 905 const intptr_t kNumInputs = 3; | 897 const intptr_t kNumInputs = 3; |
| 906 if (receiver_type() == kGrowableObjectArrayCid) { | 898 if (receiver_type() == kGrowableObjectArrayCid) { |
| 907 const intptr_t kNumTemps = 1; | 899 const intptr_t kNumTemps = 1; |
| 908 LocationSummary* locs = | 900 LocationSummary* locs = |
| 909 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 901 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 910 locs->set_in(0, Location::RequiresRegister()); | 902 locs->set_in(0, Location::RequiresRegister()); |
| 911 locs->set_in(1, Location::RequiresRegister()); | 903 locs->set_in(1, Location::RequiresRegister()); |
| 912 locs->set_in(2, Location::RequiresRegister()); | 904 locs->set_in(2, Location::RequiresRegister()); |
| 913 locs->set_temp(0, Location::RequiresRegister()); | 905 locs->set_temp(0, Location::RequiresRegister()); |
| 914 return locs; | 906 return locs; |
| 915 } else { | 907 } else { |
| 916 ASSERT(receiver_type() == kArrayCid); | 908 ASSERT(receiver_type() == kArrayCid); |
| 917 return LocationSummary::Make(kNumInputs, | 909 return LocationSummary::Make(kNumInputs, |
| 918 Location::NoLocation(), | 910 Location::NoLocation(), |
| 919 LocationSummary::kNoCall); | 911 LocationSummary::kNoCall); |
| 920 } | 912 } |
| 921 } | 913 } |
| 922 | 914 |
| 923 | 915 |
| 924 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 916 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 925 Register receiver = locs()->in(0).reg(); | 917 Register receiver = locs()->in(0).reg(); |
| 926 Register index = locs()->in(1).reg(); | 918 Register index = locs()->in(1).reg(); |
| 927 Register value = locs()->in(2).reg(); | 919 Register value = locs()->in(2).reg(); |
| 928 | 920 |
| 929 switch (receiver_type()) { | 921 switch (receiver_type()) { |
| 930 case kArrayCid: | 922 case kArrayCid: |
| 931 case kImmutableArrayCid: | 923 case kImmutableArrayCid: |
| 932 // Note that index is Smi, i.e, times 4. | 924 // Note that index is Smi, i.e, times 4. |
| 933 ASSERT(kSmiTagShift == 1); | 925 ASSERT(kSmiTagShift == 1); |
| 934 if (this->value()->NeedsStoreBuffer()) { | 926 if (this->value()->NeedsStoreBuffer()) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 959 break; | 951 break; |
| 960 } | 952 } |
| 961 | 953 |
| 962 default: | 954 default: |
| 963 UNREACHABLE(); | 955 UNREACHABLE(); |
| 964 break; | 956 break; |
| 965 } | 957 } |
| 966 } | 958 } |
| 967 | 959 |
| 968 | 960 |
| 969 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { | 961 LocationSummary* LoadInstanceFieldInstr::MakeLocationSummary() const { |
| 970 // TODO(fschneider): For this instruction the input register may be | 962 // TODO(fschneider): For this instruction the input register may be |
| 971 // reused for the result (but is not required to) because the input | 963 // reused for the result (but is not required to) because the input |
| 972 // is not used after the result is defined. We should consider adding | 964 // is not used after the result is defined. We should consider adding |
| 973 // this information to the input policy. | 965 // this information to the input policy. |
| 974 return LocationSummary::Make(1, | 966 return LocationSummary::Make(1, |
| 975 Location::RequiresRegister(), | 967 Location::RequiresRegister(), |
| 976 LocationSummary::kNoCall); | 968 LocationSummary::kNoCall); |
| 977 } | 969 } |
| 978 | 970 |
| 979 | 971 |
| 980 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 972 void LoadInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 981 Register instance_reg = locs()->in(0).reg(); | 973 Register instance_reg = locs()->in(0).reg(); |
| 982 Register result_reg = locs()->out().reg(); | 974 Register result_reg = locs()->out().reg(); |
| 983 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); | 975 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); |
| 984 } | 976 } |
| 985 | 977 |
| 986 | 978 |
| 987 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { | 979 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { |
| 988 const intptr_t kNumInputs = 2; | 980 const intptr_t kNumInputs = 2; |
| 989 const intptr_t num_temps = 0; | 981 const intptr_t num_temps = 0; |
| 990 LocationSummary* summary = | 982 LocationSummary* summary = |
| 991 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); | 983 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); |
| 992 summary->set_in(0, Location::RequiresRegister()); | 984 summary->set_in(0, Location::RequiresRegister()); |
| 993 summary->set_in(1, Location::RequiresRegister()); | 985 summary->set_in(1, Location::RequiresRegister()); |
| 994 return summary; | 986 return summary; |
| 995 } | 987 } |
| 996 | 988 |
| 997 | 989 |
| 998 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 990 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 999 Register instance_reg = locs()->in(0).reg(); | 991 Register instance_reg = locs()->in(0).reg(); |
| 1000 Register value_reg = locs()->in(1).reg(); | 992 Register value_reg = locs()->in(1).reg(); |
| 1001 if (this->value()->NeedsStoreBuffer()) { | 993 if (this->value()->NeedsStoreBuffer()) { |
| 1002 __ StoreIntoObject(instance_reg, | 994 __ StoreIntoObject(instance_reg, |
| 1003 FieldAddress(instance_reg, field().Offset()), value_reg); | 995 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 1004 } else { | 996 } else { |
| 1005 __ StoreIntoObjectNoBarrier(instance_reg, | 997 __ StoreIntoObjectNoBarrier(instance_reg, |
| 1006 FieldAddress(instance_reg, field().Offset()), value_reg); | 998 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 1007 } | 999 } |
| 1008 } | 1000 } |
| 1009 | 1001 |
| 1010 | 1002 |
| 1011 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { | 1003 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { |
| 1012 return LocationSummary::Make(0, | 1004 return LocationSummary::Make(0, |
| 1013 Location::RequiresRegister(), | 1005 Location::RequiresRegister(), |
| 1014 LocationSummary::kNoCall); | 1006 LocationSummary::kNoCall); |
| 1015 } | 1007 } |
| 1016 | 1008 |
| 1017 | 1009 |
| 1018 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1010 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1019 Register result = locs()->out().reg(); | 1011 Register result = locs()->out().reg(); |
| 1020 __ LoadObject(result, field()); | 1012 __ LoadObject(result, field()); |
| 1021 __ movq(result, FieldAddress(result, Field::value_offset())); | 1013 __ movq(result, FieldAddress(result, Field::value_offset())); |
| 1022 } | 1014 } |
| 1023 | 1015 |
| 1024 | 1016 |
| 1025 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { | 1017 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { |
| 1026 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); | 1018 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); |
| 1027 locs->set_in(0, Location::RequiresRegister()); | 1019 locs->set_in(0, Location::RequiresRegister()); |
| 1028 locs->set_temp(0, Location::RequiresRegister()); | 1020 locs->set_temp(0, Location::RequiresRegister()); |
| 1029 locs->set_out(Location::SameAsFirstInput()); | 1021 locs->set_out(Location::SameAsFirstInput()); |
| 1030 return locs; | 1022 return locs; |
| 1031 } | 1023 } |
| 1032 | 1024 |
| 1033 | 1025 |
| 1034 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1026 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1035 Register value = locs()->in(0).reg(); | 1027 Register value = locs()->in(0).reg(); |
| 1036 Register temp = locs()->temp(0).reg(); | 1028 Register temp = locs()->temp(0).reg(); |
| 1037 ASSERT(locs()->out().reg() == value); | 1029 ASSERT(locs()->out().reg() == value); |
| 1038 | 1030 |
| 1039 __ LoadObject(temp, field()); | 1031 __ LoadObject(temp, field()); |
| 1040 if (this->value()->NeedsStoreBuffer()) { | 1032 if (this->value()->NeedsStoreBuffer()) { |
| 1041 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); | 1033 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); |
| 1042 } else { | 1034 } else { |
| 1043 __ StoreIntoObjectNoBarrier( | 1035 __ StoreIntoObjectNoBarrier( |
| 1044 temp, FieldAddress(temp, Field::value_offset()), value); | 1036 temp, FieldAddress(temp, Field::value_offset()), value); |
| 1045 } | 1037 } |
| 1046 } | 1038 } |
| 1047 | 1039 |
| 1048 | 1040 |
| 1049 LocationSummary* InstanceOfComp::MakeLocationSummary() const { | 1041 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { |
| 1050 const intptr_t kNumInputs = 3; | 1042 const intptr_t kNumInputs = 3; |
| 1051 const intptr_t kNumTemps = 0; | 1043 const intptr_t kNumTemps = 0; |
| 1052 LocationSummary* summary = | 1044 LocationSummary* summary = |
| 1053 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1045 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1054 summary->set_in(0, Location::RegisterLocation(RAX)); | 1046 summary->set_in(0, Location::RegisterLocation(RAX)); |
| 1055 summary->set_in(1, Location::RegisterLocation(RCX)); | 1047 summary->set_in(1, Location::RegisterLocation(RCX)); |
| 1056 summary->set_in(2, Location::RegisterLocation(RDX)); | 1048 summary->set_in(2, Location::RegisterLocation(RDX)); |
| 1057 summary->set_out(Location::RegisterLocation(RAX)); | 1049 summary->set_out(Location::RegisterLocation(RAX)); |
| 1058 return summary; | 1050 return summary; |
| 1059 } | 1051 } |
| 1060 | 1052 |
| 1061 | 1053 |
| 1062 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1054 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1063 ASSERT(locs()->in(0).reg() == RAX); // Value. | 1055 ASSERT(locs()->in(0).reg() == RAX); // Value. |
| 1064 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. | 1056 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. |
| 1065 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. | 1057 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. |
| 1066 | 1058 |
| 1067 compiler->GenerateInstanceOf(token_pos(), | 1059 compiler->GenerateInstanceOf(token_pos(), |
| 1068 type(), | 1060 type(), |
| 1069 negate_result(), | 1061 negate_result(), |
| 1070 locs()); | 1062 locs()); |
| 1071 ASSERT(locs()->out().reg() == RAX); | 1063 ASSERT(locs()->out().reg() == RAX); |
| 1072 } | 1064 } |
| 1073 | 1065 |
| 1074 | 1066 |
| 1075 LocationSummary* CreateArrayComp::MakeLocationSummary() const { | 1067 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { |
| 1076 const intptr_t kNumInputs = 1; | 1068 const intptr_t kNumInputs = 1; |
| 1077 const intptr_t kNumTemps = 0; | 1069 const intptr_t kNumTemps = 0; |
| 1078 LocationSummary* locs = | 1070 LocationSummary* locs = |
| 1079 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1071 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1080 locs->set_in(0, Location::RegisterLocation(RBX)); | 1072 locs->set_in(0, Location::RegisterLocation(RBX)); |
| 1081 locs->set_out(Location::RegisterLocation(RAX)); | 1073 locs->set_out(Location::RegisterLocation(RAX)); |
| 1082 return locs; | 1074 return locs; |
| 1083 } | 1075 } |
| 1084 | 1076 |
| 1085 | 1077 |
| 1086 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1078 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1087 // Allocate the array. R10 = length, RBX = element type. | 1079 // Allocate the array. R10 = length, RBX = element type. |
| 1088 ASSERT(locs()->in(0).reg() == RBX); | 1080 ASSERT(locs()->in(0).reg() == RBX); |
| 1089 __ movq(R10, Immediate(Smi::RawValue(ArgumentCount()))); | 1081 __ movq(R10, Immediate(Smi::RawValue(ArgumentCount()))); |
| 1090 compiler->GenerateCall(token_pos(), | 1082 compiler->GenerateCall(token_pos(), |
| 1091 &StubCode::AllocateArrayLabel(), | 1083 &StubCode::AllocateArrayLabel(), |
| 1092 PcDescriptors::kOther, | 1084 PcDescriptors::kOther, |
| 1093 locs()); | 1085 locs()); |
| 1094 ASSERT(locs()->out().reg() == RAX); | 1086 ASSERT(locs()->out().reg() == RAX); |
| 1095 | 1087 |
| 1096 // Pop the element values from the stack into the array. | 1088 // Pop the element values from the stack into the array. |
| 1097 __ leaq(R10, FieldAddress(RAX, Array::data_offset())); | 1089 __ leaq(R10, FieldAddress(RAX, Array::data_offset())); |
| 1098 for (int i = ArgumentCount() - 1; i >= 0; --i) { | 1090 for (int i = ArgumentCount() - 1; i >= 0; --i) { |
| 1099 __ popq(Address(R10, i * kWordSize)); | 1091 __ popq(Address(R10, i * kWordSize)); |
| 1100 } | 1092 } |
| 1101 } | 1093 } |
| 1102 | 1094 |
| 1103 | 1095 |
| 1104 LocationSummary* | 1096 LocationSummary* |
| 1105 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { | 1097 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { |
| 1106 const intptr_t kNumInputs = 2; | 1098 const intptr_t kNumInputs = 2; |
| 1107 const intptr_t kNumTemps = 0; | 1099 const intptr_t kNumTemps = 0; |
| 1108 LocationSummary* locs = | 1100 LocationSummary* locs = |
| 1109 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1101 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1110 locs->set_in(0, Location::RegisterLocation(RAX)); | 1102 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 1111 locs->set_in(1, Location::RegisterLocation(RCX)); | 1103 locs->set_in(1, Location::RegisterLocation(RCX)); |
| 1112 locs->set_out(Location::RegisterLocation(RAX)); | 1104 locs->set_out(Location::RegisterLocation(RAX)); |
| 1113 return locs; | 1105 return locs; |
| 1114 } | 1106 } |
| 1115 | 1107 |
| 1116 | 1108 |
| 1117 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( | 1109 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( |
| 1118 FlowGraphCompiler* compiler) { | 1110 FlowGraphCompiler* compiler) { |
| 1119 const Class& cls = Class::ZoneHandle(constructor().Owner()); | 1111 const Class& cls = Class::ZoneHandle(constructor().Owner()); |
| 1120 Register type_arguments = locs()->in(0).reg(); | 1112 Register type_arguments = locs()->in(0).reg(); |
| 1121 Register instantiator_type_arguments = locs()->in(1).reg(); | 1113 Register instantiator_type_arguments = locs()->in(1).reg(); |
| 1122 Register result = locs()->out().reg(); | 1114 Register result = locs()->out().reg(); |
| 1123 | 1115 |
| 1124 // Push the result place holder initialized to NULL. | 1116 // Push the result place holder initialized to NULL. |
| 1125 __ PushObject(Object::ZoneHandle()); | 1117 __ PushObject(Object::ZoneHandle()); |
| 1126 __ PushObject(cls); | 1118 __ PushObject(cls); |
| 1127 __ pushq(type_arguments); | 1119 __ pushq(type_arguments); |
| 1128 __ pushq(instantiator_type_arguments); | 1120 __ pushq(instantiator_type_arguments); |
| 1129 compiler->GenerateCallRuntime(token_pos(), | 1121 compiler->GenerateCallRuntime(token_pos(), |
| 1130 kAllocateObjectWithBoundsCheckRuntimeEntry, | 1122 kAllocateObjectWithBoundsCheckRuntimeEntry, |
| 1131 locs()); | 1123 locs()); |
| 1132 // Pop instantiator type arguments, type arguments, and class. | 1124 // Pop instantiator type arguments, type arguments, and class. |
| 1133 __ Drop(3); | 1125 __ Drop(3); |
| 1134 __ popq(result); // Pop new instance. | 1126 __ popq(result); // Pop new instance. |
| 1135 } | 1127 } |
| 1136 | 1128 |
| 1137 | 1129 |
| 1138 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { | 1130 LocationSummary* LoadVMFieldInstr::MakeLocationSummary() const { |
| 1139 return LocationSummary::Make(1, | 1131 return LocationSummary::Make(1, |
| 1140 Location::RequiresRegister(), | 1132 Location::RequiresRegister(), |
| 1141 LocationSummary::kNoCall); | 1133 LocationSummary::kNoCall); |
| 1142 } | 1134 } |
| 1143 | 1135 |
| 1144 | 1136 |
| 1145 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1137 void LoadVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1146 Register instance_reg = locs()->in(0).reg(); | 1138 Register instance_reg = locs()->in(0).reg(); |
| 1147 Register result_reg = locs()->out().reg(); | 1139 Register result_reg = locs()->out().reg(); |
| 1148 | 1140 |
| 1149 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); | 1141 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); |
| 1150 } | 1142 } |
| 1151 | 1143 |
| 1152 | 1144 |
| 1153 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { | 1145 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { |
| 1154 const intptr_t kNumInputs = 1; | 1146 const intptr_t kNumInputs = 1; |
| 1155 const intptr_t kNumTemps = 0; | 1147 const intptr_t kNumTemps = 0; |
| 1156 LocationSummary* locs = | 1148 LocationSummary* locs = |
| 1157 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1149 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1158 locs->set_in(0, Location::RegisterLocation(RAX)); | 1150 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 1159 locs->set_out(Location::RegisterLocation(RAX)); | 1151 locs->set_out(Location::RegisterLocation(RAX)); |
| 1160 return locs; | 1152 return locs; |
| 1161 } | 1153 } |
| 1162 | 1154 |
| 1163 | 1155 |
| 1164 void InstantiateTypeArgumentsComp::EmitNativeCode( | 1156 void InstantiateTypeArgumentsInstr::EmitNativeCode( |
| 1165 FlowGraphCompiler* compiler) { | 1157 FlowGraphCompiler* compiler) { |
| 1166 Register instantiator_reg = locs()->in(0).reg(); | 1158 Register instantiator_reg = locs()->in(0).reg(); |
| 1167 Register result_reg = locs()->out().reg(); | 1159 Register result_reg = locs()->out().reg(); |
| 1168 | 1160 |
| 1169 // 'instantiator_reg' is the instantiator AbstractTypeArguments object | 1161 // 'instantiator_reg' is the instantiator AbstractTypeArguments object |
| 1170 // (or null). | 1162 // (or null). |
| 1171 // If the instantiator is null and if the type argument vector | 1163 // If the instantiator is null and if the type argument vector |
| 1172 // instantiated from null becomes a vector of Dynamic, then use null as | 1164 // instantiated from null becomes a vector of Dynamic, then use null as |
| 1173 // the type arguments. | 1165 // the type arguments. |
| 1174 Label type_arguments_instantiated; | 1166 Label type_arguments_instantiated; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1203 locs()); | 1195 locs()); |
| 1204 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 1196 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
| 1205 __ popq(result_reg); // Pop instantiated type arguments. | 1197 __ popq(result_reg); // Pop instantiated type arguments. |
| 1206 __ Bind(&type_arguments_instantiated); | 1198 __ Bind(&type_arguments_instantiated); |
| 1207 ASSERT(instantiator_reg == result_reg); | 1199 ASSERT(instantiator_reg == result_reg); |
| 1208 // 'result_reg': Instantiated type arguments. | 1200 // 'result_reg': Instantiated type arguments. |
| 1209 } | 1201 } |
| 1210 | 1202 |
| 1211 | 1203 |
| 1212 LocationSummary* | 1204 LocationSummary* |
| 1213 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { | 1205 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { |
| 1214 const intptr_t kNumInputs = 1; | 1206 const intptr_t kNumInputs = 1; |
| 1215 const intptr_t kNumTemps = 0; | 1207 const intptr_t kNumTemps = 0; |
| 1216 LocationSummary* locs = | 1208 LocationSummary* locs = |
| 1217 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1209 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1218 locs->set_in(0, Location::RequiresRegister()); | 1210 locs->set_in(0, Location::RequiresRegister()); |
| 1219 locs->set_out(Location::SameAsFirstInput()); | 1211 locs->set_out(Location::SameAsFirstInput()); |
| 1220 return locs; | 1212 return locs; |
| 1221 } | 1213 } |
| 1222 | 1214 |
| 1223 | 1215 |
| 1224 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( | 1216 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( |
| 1225 FlowGraphCompiler* compiler) { | 1217 FlowGraphCompiler* compiler) { |
| 1226 Register instantiator_reg = locs()->in(0).reg(); | 1218 Register instantiator_reg = locs()->in(0).reg(); |
| 1227 Register result_reg = locs()->out().reg(); | 1219 Register result_reg = locs()->out().reg(); |
| 1228 ASSERT(instantiator_reg == result_reg); | 1220 ASSERT(instantiator_reg == result_reg); |
| 1229 | 1221 |
| 1230 // instantiator_reg is the instantiator type argument vector, i.e. an | 1222 // instantiator_reg is the instantiator type argument vector, i.e. an |
| 1231 // AbstractTypeArguments object (or null). | 1223 // AbstractTypeArguments object (or null). |
| 1232 // If the instantiator is null and if the type argument vector | 1224 // If the instantiator is null and if the type argument vector |
| 1233 // instantiated from null becomes a vector of Dynamic, then use null as | 1225 // instantiated from null becomes a vector of Dynamic, then use null as |
| 1234 // the type arguments. | 1226 // the type arguments. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1259 // In the non-factory case, we rely on the allocation stub to | 1251 // In the non-factory case, we rely on the allocation stub to |
| 1260 // instantiate the type arguments. | 1252 // instantiate the type arguments. |
| 1261 __ LoadObject(result_reg, type_arguments()); | 1253 __ LoadObject(result_reg, type_arguments()); |
| 1262 // result_reg: uninstantiated type arguments. | 1254 // result_reg: uninstantiated type arguments. |
| 1263 __ Bind(&type_arguments_instantiated); | 1255 __ Bind(&type_arguments_instantiated); |
| 1264 // result_reg: uninstantiated or instantiated type arguments. | 1256 // result_reg: uninstantiated or instantiated type arguments. |
| 1265 } | 1257 } |
| 1266 | 1258 |
| 1267 | 1259 |
| 1268 LocationSummary* | 1260 LocationSummary* |
| 1269 ExtractConstructorInstantiatorComp::MakeLocationSummary() const { | 1261 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { |
| 1270 const intptr_t kNumInputs = 1; | 1262 const intptr_t kNumInputs = 1; |
| 1271 const intptr_t kNumTemps = 0; | 1263 const intptr_t kNumTemps = 0; |
| 1272 LocationSummary* locs = | 1264 LocationSummary* locs = |
| 1273 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1265 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1274 locs->set_in(0, Location::RequiresRegister()); | 1266 locs->set_in(0, Location::RequiresRegister()); |
| 1275 locs->set_out(Location::SameAsFirstInput()); | 1267 locs->set_out(Location::SameAsFirstInput()); |
| 1276 return locs; | 1268 return locs; |
| 1277 } | 1269 } |
| 1278 | 1270 |
| 1279 | 1271 |
| 1280 void ExtractConstructorInstantiatorComp::EmitNativeCode( | 1272 void ExtractConstructorInstantiatorInstr::EmitNativeCode( |
| 1281 FlowGraphCompiler* compiler) { | 1273 FlowGraphCompiler* compiler) { |
| 1282 Register instantiator_reg = locs()->in(0).reg(); | 1274 Register instantiator_reg = locs()->in(0).reg(); |
| 1283 ASSERT(locs()->out().reg() == instantiator_reg); | 1275 ASSERT(locs()->out().reg() == instantiator_reg); |
| 1284 | 1276 |
| 1285 // instantiator_reg is the instantiator AbstractTypeArguments object | 1277 // instantiator_reg is the instantiator AbstractTypeArguments object |
| 1286 // (or null). If the instantiator is null and if the type argument vector | 1278 // (or null). If the instantiator is null and if the type argument vector |
| 1287 // instantiated from null becomes a vector of Dynamic, then use null as | 1279 // instantiated from null becomes a vector of Dynamic, then use null as |
| 1288 // the type arguments and do not pass the instantiator. | 1280 // the type arguments and do not pass the instantiator. |
| 1289 Label done; | 1281 Label done; |
| 1290 const intptr_t len = type_arguments().Length(); | 1282 const intptr_t len = type_arguments().Length(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 // The instantiator was used in VisitExtractConstructorTypeArguments as the | 1315 // The instantiator was used in VisitExtractConstructorTypeArguments as the |
| 1324 // instantiated type arguments, no proper instantiator needed. | 1316 // instantiated type arguments, no proper instantiator needed. |
| 1325 __ movq(instantiator_reg, | 1317 __ movq(instantiator_reg, |
| 1326 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1318 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
| 1327 } | 1319 } |
| 1328 __ Bind(&done); | 1320 __ Bind(&done); |
| 1329 // instantiator_reg: instantiator or kNoInstantiator. | 1321 // instantiator_reg: instantiator or kNoInstantiator. |
| 1330 } | 1322 } |
| 1331 | 1323 |
| 1332 | 1324 |
| 1333 LocationSummary* AllocateContextComp::MakeLocationSummary() const { | 1325 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { |
| 1334 const intptr_t kNumInputs = 0; | 1326 const intptr_t kNumInputs = 0; |
| 1335 const intptr_t kNumTemps = 1; | 1327 const intptr_t kNumTemps = 1; |
| 1336 LocationSummary* locs = | 1328 LocationSummary* locs = |
| 1337 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1329 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1338 locs->set_temp(0, Location::RegisterLocation(R10)); | 1330 locs->set_temp(0, Location::RegisterLocation(R10)); |
| 1339 locs->set_out(Location::RegisterLocation(RAX)); | 1331 locs->set_out(Location::RegisterLocation(RAX)); |
| 1340 return locs; | 1332 return locs; |
| 1341 } | 1333 } |
| 1342 | 1334 |
| 1343 | 1335 |
| 1344 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1336 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1345 ASSERT(locs()->temp(0).reg() == R10); | 1337 ASSERT(locs()->temp(0).reg() == R10); |
| 1346 ASSERT(locs()->out().reg() == RAX); | 1338 ASSERT(locs()->out().reg() == RAX); |
| 1347 | 1339 |
| 1348 __ movq(R10, Immediate(num_context_variables())); | 1340 __ movq(R10, Immediate(num_context_variables())); |
| 1349 const ExternalLabel label("alloc_context", | 1341 const ExternalLabel label("alloc_context", |
| 1350 StubCode::AllocateContextEntryPoint()); | 1342 StubCode::AllocateContextEntryPoint()); |
| 1351 compiler->GenerateCall(token_pos(), | 1343 compiler->GenerateCall(token_pos(), |
| 1352 &label, | 1344 &label, |
| 1353 PcDescriptors::kOther, | 1345 PcDescriptors::kOther, |
| 1354 locs()); | 1346 locs()); |
| 1355 } | 1347 } |
| 1356 | 1348 |
| 1357 | 1349 |
| 1358 LocationSummary* CloneContextComp::MakeLocationSummary() const { | 1350 LocationSummary* CloneContextInstr::MakeLocationSummary() const { |
| 1359 const intptr_t kNumInputs = 1; | 1351 const intptr_t kNumInputs = 1; |
| 1360 const intptr_t kNumTemps = 0; | 1352 const intptr_t kNumTemps = 0; |
| 1361 LocationSummary* locs = | 1353 LocationSummary* locs = |
| 1362 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1354 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1363 locs->set_in(0, Location::RegisterLocation(RAX)); | 1355 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 1364 locs->set_out(Location::RegisterLocation(RAX)); | 1356 locs->set_out(Location::RegisterLocation(RAX)); |
| 1365 return locs; | 1357 return locs; |
| 1366 } | 1358 } |
| 1367 | 1359 |
| 1368 | 1360 |
| 1369 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1361 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1370 Register context_value = locs()->in(0).reg(); | 1362 Register context_value = locs()->in(0).reg(); |
| 1371 Register result = locs()->out().reg(); | 1363 Register result = locs()->out().reg(); |
| 1372 | 1364 |
| 1373 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1365 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 1374 __ pushq(context_value); | 1366 __ pushq(context_value); |
| 1375 compiler->GenerateCallRuntime(token_pos(), | 1367 compiler->GenerateCallRuntime(token_pos(), |
| 1376 kCloneContextRuntimeEntry, | 1368 kCloneContextRuntimeEntry, |
| 1377 locs()); | 1369 locs()); |
| 1378 __ popq(result); // Remove argument. | 1370 __ popq(result); // Remove argument. |
| 1379 __ popq(result); // Get result (cloned context). | 1371 __ popq(result); // Get result (cloned context). |
| 1380 } | 1372 } |
| 1381 | 1373 |
| 1382 | 1374 |
| 1383 LocationSummary* CatchEntryComp::MakeLocationSummary() const { | 1375 LocationSummary* CatchEntryInstr::MakeLocationSummary() const { |
| 1384 return LocationSummary::Make(0, | 1376 return LocationSummary::Make(0, |
| 1385 Location::NoLocation(), | 1377 Location::NoLocation(), |
| 1386 LocationSummary::kNoCall); | 1378 LocationSummary::kNoCall); |
| 1387 } | 1379 } |
| 1388 | 1380 |
| 1389 | 1381 |
| 1390 // Restore stack and initialize the two exception variables: | 1382 // Restore stack and initialize the two exception variables: |
| 1391 // exception and stack trace variables. | 1383 // exception and stack trace variables. |
| 1392 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1384 void CatchEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1393 // Restore RSP from RBP as we are coming from a throw and the code for | 1385 // Restore RSP from RBP as we are coming from a throw and the code for |
| 1394 // popping arguments has not been run. | 1386 // popping arguments has not been run. |
| 1395 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; | 1387 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; |
| 1396 ASSERT(locals_space_size >= 0); | 1388 ASSERT(locals_space_size >= 0); |
| 1397 const intptr_t offset_size = | 1389 const intptr_t offset_size = |
| 1398 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; | 1390 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; |
| 1399 __ leaq(RSP, Address(RBP, offset_size)); | 1391 __ leaq(RSP, Address(RBP, offset_size)); |
| 1400 | 1392 |
| 1401 ASSERT(!exception_var().is_captured()); | 1393 ASSERT(!exception_var().is_captured()); |
| 1402 ASSERT(!stacktrace_var().is_captured()); | 1394 ASSERT(!stacktrace_var().is_captured()); |
| 1403 __ movq(Address(RBP, exception_var().index() * kWordSize), | 1395 __ movq(Address(RBP, exception_var().index() * kWordSize), |
| 1404 kExceptionObjectReg); | 1396 kExceptionObjectReg); |
| 1405 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), | 1397 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), |
| 1406 kStackTraceObjectReg); | 1398 kStackTraceObjectReg); |
| 1407 } | 1399 } |
| 1408 | 1400 |
| 1409 | 1401 |
| 1410 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { | 1402 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { |
| 1411 const intptr_t kNumInputs = 0; | 1403 const intptr_t kNumInputs = 0; |
| 1412 const intptr_t kNumTemps = 1; | 1404 const intptr_t kNumTemps = 1; |
| 1413 LocationSummary* summary = | 1405 LocationSummary* summary = |
| 1414 new LocationSummary(kNumInputs, | 1406 new LocationSummary(kNumInputs, |
| 1415 kNumTemps, | 1407 kNumTemps, |
| 1416 LocationSummary::kCallOnSlowPath); | 1408 LocationSummary::kCallOnSlowPath); |
| 1417 summary->set_temp(0, Location::RequiresRegister()); | 1409 summary->set_temp(0, Location::RequiresRegister()); |
| 1418 return summary; | 1410 return summary; |
| 1419 } | 1411 } |
| 1420 | 1412 |
| 1421 | 1413 |
| 1422 class CheckStackOverflowSlowPath : public SlowPathCode { | 1414 class CheckStackOverflowSlowPath : public SlowPathCode { |
| 1423 public: | 1415 public: |
| 1424 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation) | 1416 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) |
| 1425 : computation_(computation) { } | 1417 : instruction_(instruction) { } |
| 1426 | 1418 |
| 1427 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1419 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1428 __ Bind(entry_label()); | 1420 __ Bind(entry_label()); |
| 1429 compiler->SaveLiveRegisters(computation_->locs()); | 1421 compiler->SaveLiveRegisters(instruction_->locs()); |
| 1430 compiler->GenerateCallRuntime(computation_->token_pos(), | 1422 compiler->GenerateCallRuntime(instruction_->token_pos(), |
| 1431 kStackOverflowRuntimeEntry, | 1423 kStackOverflowRuntimeEntry, |
| 1432 computation_->locs()); | 1424 instruction_->locs()); |
| 1433 compiler->RestoreLiveRegisters(computation_->locs()); | 1425 compiler->RestoreLiveRegisters(instruction_->locs()); |
| 1434 __ jmp(exit_label()); | 1426 __ jmp(exit_label()); |
| 1435 } | 1427 } |
| 1436 | 1428 |
| 1437 private: | 1429 private: |
| 1438 CheckStackOverflowComp* computation_; | 1430 CheckStackOverflowInstr* instruction_; |
| 1439 }; | 1431 }; |
| 1440 | 1432 |
| 1441 | 1433 |
| 1442 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1434 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1443 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); | 1435 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); |
| 1444 compiler->AddSlowPathCode(slow_path); | 1436 compiler->AddSlowPathCode(slow_path); |
| 1445 | 1437 |
| 1446 Register temp = locs()->temp(0).reg(); | 1438 Register temp = locs()->temp(0).reg(); |
| 1447 // Generate stack overflow check. | 1439 // Generate stack overflow check. |
| 1448 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); | 1440 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); |
| 1449 __ cmpq(RSP, Address(temp, 0)); | 1441 __ cmpq(RSP, Address(temp, 0)); |
| 1450 __ j(BELOW_EQUAL, slow_path->entry_label()); | 1442 __ j(BELOW_EQUAL, slow_path->entry_label()); |
| 1451 __ Bind(slow_path->exit_label()); | 1443 __ Bind(slow_path->exit_label()); |
| 1452 } | 1444 } |
| 1453 | 1445 |
| 1454 | 1446 |
| 1455 static bool CanBeImmediate(const Object& constant) { | 1447 static bool CanBeImmediate(const Object& constant) { |
| 1456 return constant.IsSmi() && | 1448 return constant.IsSmi() && |
| 1457 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32(); | 1449 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32(); |
| 1458 } | 1450 } |
| 1459 | 1451 |
| 1460 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const { | 1452 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { |
| 1461 const intptr_t kNumInputs = 2; | 1453 const intptr_t kNumInputs = 2; |
| 1462 | 1454 |
| 1463 ConstantComp* right_constant = right()->definition()->AsConstant(); | 1455 ConstantInstr* right_constant = right()->definition()->AsConstant(); |
| 1464 if ((right_constant != NULL) && | 1456 if ((right_constant != NULL) && |
| 1465 (op_kind() != Token::kTRUNCDIV) && | 1457 (op_kind() != Token::kTRUNCDIV) && |
| 1466 (op_kind() != Token::kSHL) && | 1458 (op_kind() != Token::kSHL) && |
| 1467 (op_kind() != Token::kMUL) && | 1459 (op_kind() != Token::kMUL) && |
| 1468 CanBeImmediate(right_constant->value())) { | 1460 CanBeImmediate(right_constant->value())) { |
| 1469 const intptr_t kNumTemps = 0; | 1461 const intptr_t kNumTemps = 0; |
| 1470 LocationSummary* summary = | 1462 LocationSummary* summary = |
| 1471 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1463 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1472 summary->set_in(0, Location::RequiresRegister()); | 1464 summary->set_in(0, Location::RequiresRegister()); |
| 1473 summary->set_in(1, Location::Constant(right_constant->value())); | 1465 summary->set_in(1, Location::Constant(right_constant->value())); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1511 LocationSummary* summary = | 1503 LocationSummary* summary = |
| 1512 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1504 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1513 summary->set_in(0, Location::RequiresRegister()); | 1505 summary->set_in(0, Location::RequiresRegister()); |
| 1514 summary->set_in(1, Location::RequiresRegister()); | 1506 summary->set_in(1, Location::RequiresRegister()); |
| 1515 summary->set_out(Location::SameAsFirstInput()); | 1507 summary->set_out(Location::SameAsFirstInput()); |
| 1516 return summary; | 1508 return summary; |
| 1517 } | 1509 } |
| 1518 } | 1510 } |
| 1519 | 1511 |
| 1520 | 1512 |
| 1521 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1513 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1522 Register left = locs()->in(0).reg(); | 1514 Register left = locs()->in(0).reg(); |
| 1523 Register result = locs()->out().reg(); | 1515 Register result = locs()->out().reg(); |
| 1524 ASSERT(left == result); | 1516 ASSERT(left == result); |
| 1525 Label* deopt = NULL; | 1517 Label* deopt = NULL; |
| 1526 switch (op_kind()) { | 1518 switch (op_kind()) { |
| 1527 case Token::kBIT_AND: | 1519 case Token::kBIT_AND: |
| 1528 case Token::kBIT_OR: | 1520 case Token::kBIT_OR: |
| 1529 case Token::kBIT_XOR: | 1521 case Token::kBIT_XOR: |
| 1530 // Can't deoptimize. Arguments are already checked for smi. | 1522 // Can't deoptimize. Arguments are already checked for smi. |
| 1531 break; | 1523 break; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1726 UNREACHABLE(); | 1718 UNREACHABLE(); |
| 1727 break; | 1719 break; |
| 1728 } | 1720 } |
| 1729 default: | 1721 default: |
| 1730 UNREACHABLE(); | 1722 UNREACHABLE(); |
| 1731 break; | 1723 break; |
| 1732 } | 1724 } |
| 1733 } | 1725 } |
| 1734 | 1726 |
| 1735 | 1727 |
| 1736 LocationSummary* BinaryMintOpComp::MakeLocationSummary() const { | 1728 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { |
| 1737 ASSERT(op_kind() == Token::kBIT_AND); | 1729 ASSERT(op_kind() == Token::kBIT_AND); |
| 1738 const intptr_t kNumInputs = 2; | 1730 const intptr_t kNumInputs = 2; |
| 1739 const intptr_t kNumTemps = 0; | 1731 const intptr_t kNumTemps = 0; |
| 1740 LocationSummary* summary = | 1732 LocationSummary* summary = |
| 1741 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1733 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1742 summary->set_in(0, Location::RegisterLocation(RAX)); | 1734 summary->set_in(0, Location::RegisterLocation(RAX)); |
| 1743 summary->set_in(1, Location::RegisterLocation(RCX)); | 1735 summary->set_in(1, Location::RegisterLocation(RCX)); |
| 1744 summary->set_out(Location::RegisterLocation(RAX)); | 1736 summary->set_out(Location::RegisterLocation(RAX)); |
| 1745 return summary; | 1737 return summary; |
| 1746 } | 1738 } |
| 1747 | 1739 |
| 1748 | 1740 |
| 1749 void BinaryMintOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1741 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1750 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi | 1742 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi |
| 1751 // receiver and a Mint or Smi argument. We fall back to the run time call if | 1743 // receiver and a Mint or Smi argument. We fall back to the run time call if |
| 1752 // both receiver and argument are Mint or if one of them is Mint and the other | 1744 // both receiver and argument are Mint or if one of them is Mint and the other |
| 1753 // is a negative Smi. | 1745 // is a negative Smi. |
| 1754 Register left = locs()->in(0).reg(); | 1746 Register left = locs()->in(0).reg(); |
| 1755 Register right = locs()->in(1).reg(); | 1747 Register right = locs()->in(1).reg(); |
| 1756 Register result = locs()->out().reg(); | 1748 Register result = locs()->out().reg(); |
| 1757 ASSERT(left == result); | 1749 ASSERT(left == result); |
| 1758 ASSERT(op_kind() == Token::kBIT_AND); | 1750 ASSERT(op_kind() == Token::kBIT_AND); |
| 1759 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 1751 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1828 instance_call()->ArgumentCount(), | 1820 instance_call()->ArgumentCount(), |
| 1829 instance_call()->argument_names(), | 1821 instance_call()->argument_names(), |
| 1830 locs()); | 1822 locs()); |
| 1831 ASSERT(result == RAX); | 1823 ASSERT(result == RAX); |
| 1832 } | 1824 } |
| 1833 } | 1825 } |
| 1834 __ Bind(&done); | 1826 __ Bind(&done); |
| 1835 } | 1827 } |
| 1836 | 1828 |
| 1837 | 1829 |
| 1838 LocationSummary* CheckEitherNonSmiComp::MakeLocationSummary() const { | 1830 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { |
| 1839 ASSERT((left()->ResultCid() != kDoubleCid) && | 1831 ASSERT((left()->ResultCid() != kDoubleCid) && |
| 1840 (right()->ResultCid() != kDoubleCid)); | 1832 (right()->ResultCid() != kDoubleCid)); |
| 1841 const intptr_t kNumInputs = 2; | 1833 const intptr_t kNumInputs = 2; |
| 1842 const intptr_t kNumTemps = 1; | 1834 const intptr_t kNumTemps = 1; |
| 1843 LocationSummary* summary = | 1835 LocationSummary* summary = |
| 1844 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1836 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1845 summary->set_in(0, Location::RequiresRegister()); | 1837 summary->set_in(0, Location::RequiresRegister()); |
| 1846 summary->set_in(1, Location::RequiresRegister()); | 1838 summary->set_in(1, Location::RequiresRegister()); |
| 1847 summary->set_temp(0, Location::RequiresRegister()); | 1839 summary->set_temp(0, Location::RequiresRegister()); |
| 1848 return summary; | 1840 return summary; |
| 1849 } | 1841 } |
| 1850 | 1842 |
| 1851 | 1843 |
| 1852 void CheckEitherNonSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1844 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1853 Label* deopt = compiler->AddDeoptStub(instance_call_->deopt_id(), | 1845 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryDoubleOp); |
| 1854 kDeoptBinaryDoubleOp); | |
| 1855 | |
| 1856 Register temp = locs()->temp(0).reg(); | 1846 Register temp = locs()->temp(0).reg(); |
| 1857 __ movq(temp, locs()->in(0).reg()); | 1847 __ movq(temp, locs()->in(0).reg()); |
| 1858 __ orq(temp, locs()->in(1).reg()); | 1848 __ orq(temp, locs()->in(1).reg()); |
| 1859 __ testl(temp, Immediate(kSmiTagMask)); | 1849 __ testl(temp, Immediate(kSmiTagMask)); |
| 1860 __ j(ZERO, deopt); | 1850 __ j(ZERO, deopt); |
| 1861 } | 1851 } |
| 1862 | 1852 |
| 1863 | 1853 |
| 1864 LocationSummary* BoxDoubleComp::MakeLocationSummary() const { | 1854 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { |
| 1865 const intptr_t kNumInputs = 1; | 1855 const intptr_t kNumInputs = 1; |
| 1866 const intptr_t kNumTemps = 0; | 1856 const intptr_t kNumTemps = 0; |
| 1867 LocationSummary* summary = | 1857 LocationSummary* summary = |
| 1868 new LocationSummary(kNumInputs, | 1858 new LocationSummary(kNumInputs, |
| 1869 kNumTemps, | 1859 kNumTemps, |
| 1870 LocationSummary::kCallOnSlowPath); | 1860 LocationSummary::kCallOnSlowPath); |
| 1871 summary->set_in(0, Location::RequiresXmmRegister()); | 1861 summary->set_in(0, Location::RequiresXmmRegister()); |
| 1872 summary->set_out(Location::RequiresRegister()); | 1862 summary->set_out(Location::RequiresRegister()); |
| 1873 return summary; | 1863 return summary; |
| 1874 } | 1864 } |
| 1875 | 1865 |
| 1876 | 1866 |
| 1877 class BoxDoubleSlowPath : public SlowPathCode { | 1867 class BoxDoubleSlowPath : public SlowPathCode { |
| 1878 public: | 1868 public: |
| 1879 explicit BoxDoubleSlowPath(BoxDoubleComp* computation) | 1869 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction) |
| 1880 : computation_(computation) { } | 1870 : instruction_(instruction) { } |
| 1881 | 1871 |
| 1882 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1872 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1883 __ Bind(entry_label()); | 1873 __ Bind(entry_label()); |
| 1884 const Class& double_class = compiler->double_class(); | 1874 const Class& double_class = compiler->double_class(); |
| 1885 const Code& stub = | 1875 const Code& stub = |
| 1886 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1876 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1887 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 1877 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1888 | 1878 |
| 1889 LocationSummary* locs = computation_->locs(); | 1879 LocationSummary* locs = instruction_->locs(); |
| 1890 locs->live_registers()->Remove(locs->out()); | 1880 locs->live_registers()->Remove(locs->out()); |
| 1891 | 1881 |
| 1892 compiler->SaveLiveRegisters(locs); | 1882 compiler->SaveLiveRegisters(locs); |
| 1893 compiler->GenerateCall(computation_->token_pos(), | 1883 compiler->GenerateCall(instruction_->token_pos(), |
| 1894 &label, | 1884 &label, |
| 1895 PcDescriptors::kOther, | 1885 PcDescriptors::kOther, |
| 1896 locs); | 1886 locs); |
| 1897 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX); | 1887 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX); |
| 1898 compiler->RestoreLiveRegisters(locs); | 1888 compiler->RestoreLiveRegisters(locs); |
| 1899 | 1889 |
| 1900 __ jmp(exit_label()); | 1890 __ jmp(exit_label()); |
| 1901 } | 1891 } |
| 1902 | 1892 |
| 1903 private: | 1893 private: |
| 1904 BoxDoubleComp* computation_; | 1894 BoxDoubleInstr* instruction_; |
| 1905 }; | 1895 }; |
| 1906 | 1896 |
| 1907 | 1897 |
| 1908 void BoxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1898 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1909 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 1899 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 1910 compiler->AddSlowPathCode(slow_path); | 1900 compiler->AddSlowPathCode(slow_path); |
| 1911 | 1901 |
| 1912 Register out_reg = locs()->out().reg(); | 1902 Register out_reg = locs()->out().reg(); |
| 1913 XmmRegister value = locs()->in(0).xmm_reg(); | 1903 XmmRegister value = locs()->in(0).xmm_reg(); |
| 1914 | 1904 |
| 1915 AssemblerMacros::TryAllocate(compiler->assembler(), | 1905 AssemblerMacros::TryAllocate(compiler->assembler(), |
| 1916 compiler->double_class(), | 1906 compiler->double_class(), |
| 1917 slow_path->entry_label(), | 1907 slow_path->entry_label(), |
| 1918 Assembler::kFarJump, | 1908 Assembler::kFarJump, |
| 1919 out_reg); | 1909 out_reg); |
| 1920 __ Bind(slow_path->exit_label()); | 1910 __ Bind(slow_path->exit_label()); |
| 1921 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); | 1911 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); |
| 1922 } | 1912 } |
| 1923 | 1913 |
| 1924 | 1914 |
| 1925 LocationSummary* UnboxDoubleComp::MakeLocationSummary() const { | 1915 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { |
| 1926 const intptr_t v_cid = value()->ResultCid(); | 1916 const intptr_t v_cid = value()->ResultCid(); |
| 1927 | 1917 |
| 1928 const intptr_t kNumInputs = 1; | 1918 const intptr_t kNumInputs = 1; |
| 1929 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; | 1919 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; |
| 1930 LocationSummary* summary = | 1920 LocationSummary* summary = |
| 1931 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1921 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1932 summary->set_in(0, Location::RequiresRegister()); | 1922 summary->set_in(0, Location::RequiresRegister()); |
| 1933 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); | 1923 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); |
| 1934 summary->set_out(Location::RequiresXmmRegister()); | 1924 summary->set_out(Location::RequiresXmmRegister()); |
| 1935 return summary; | 1925 return summary; |
| 1936 } | 1926 } |
| 1937 | 1927 |
| 1938 | 1928 |
| 1939 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1929 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1940 const intptr_t v_cid = value()->ResultCid(); | 1930 const intptr_t v_cid = value()->ResultCid(); |
| 1941 | 1931 |
| 1942 const Register value = locs()->in(0).reg(); | 1932 const Register value = locs()->in(0).reg(); |
| 1943 const XmmRegister result = locs()->out().xmm_reg(); | 1933 const XmmRegister result = locs()->out().xmm_reg(); |
| 1944 if (v_cid != kDoubleCid) { | 1934 if (v_cid != kDoubleCid) { |
| 1945 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); | 1935 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); |
| 1946 compiler->LoadDoubleOrSmiToXmm(result, | 1936 compiler->LoadDoubleOrSmiToXmm(result, |
| 1947 value, | 1937 value, |
| 1948 locs()->temp(0).reg(), | 1938 locs()->temp(0).reg(), |
| 1949 deopt); | 1939 deopt); |
| 1950 } else { | 1940 } else { |
| 1951 __ movsd(result, FieldAddress(value, Double::value_offset())); | 1941 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 1952 } | 1942 } |
| 1953 } | 1943 } |
| 1954 | 1944 |
| 1955 | 1945 |
| 1956 LocationSummary* UnboxedDoubleBinaryOpComp::MakeLocationSummary() const { | 1946 LocationSummary* UnboxedDoubleBinaryOpInstr::MakeLocationSummary() const { |
| 1957 const intptr_t kNumInputs = 2; | 1947 const intptr_t kNumInputs = 2; |
| 1958 const intptr_t kNumTemps = 0; | 1948 const intptr_t kNumTemps = 0; |
| 1959 LocationSummary* summary = | 1949 LocationSummary* summary = |
| 1960 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1950 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1961 summary->set_in(0, Location::RequiresXmmRegister()); | 1951 summary->set_in(0, Location::RequiresXmmRegister()); |
| 1962 summary->set_in(1, Location::RequiresXmmRegister()); | 1952 summary->set_in(1, Location::RequiresXmmRegister()); |
| 1963 summary->set_out(Location::SameAsFirstInput()); | 1953 summary->set_out(Location::SameAsFirstInput()); |
| 1964 return summary; | 1954 return summary; |
| 1965 } | 1955 } |
| 1966 | 1956 |
| 1967 | 1957 |
| 1968 void UnboxedDoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1958 void UnboxedDoubleBinaryOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1969 XmmRegister left = locs()->in(0).xmm_reg(); | 1959 XmmRegister left = locs()->in(0).xmm_reg(); |
| 1970 XmmRegister right = locs()->in(1).xmm_reg(); | 1960 XmmRegister right = locs()->in(1).xmm_reg(); |
| 1971 | 1961 |
| 1972 ASSERT(locs()->out().xmm_reg() == left); | 1962 ASSERT(locs()->out().xmm_reg() == left); |
| 1973 | 1963 |
| 1974 switch (op_kind()) { | 1964 switch (op_kind()) { |
| 1975 case Token::kADD: __ addsd(left, right); break; | 1965 case Token::kADD: __ addsd(left, right); break; |
| 1976 case Token::kSUB: __ subsd(left, right); break; | 1966 case Token::kSUB: __ subsd(left, right); break; |
| 1977 case Token::kMUL: __ mulsd(left, right); break; | 1967 case Token::kMUL: __ mulsd(left, right); break; |
| 1978 case Token::kDIV: __ divsd(left, right); break; | 1968 case Token::kDIV: __ divsd(left, right); break; |
| 1979 default: UNREACHABLE(); | 1969 default: UNREACHABLE(); |
| 1980 } | 1970 } |
| 1981 } | 1971 } |
| 1982 | 1972 |
| 1983 | 1973 |
| 1984 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { | 1974 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
| 1985 const intptr_t kNumInputs = 1; | 1975 const intptr_t kNumInputs = 1; |
| 1986 const intptr_t kNumTemps = 0; | 1976 const intptr_t kNumTemps = 0; |
| 1987 LocationSummary* summary = | 1977 LocationSummary* summary = |
| 1988 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1978 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1989 summary->set_in(0, Location::RequiresRegister()); | 1979 summary->set_in(0, Location::RequiresRegister()); |
| 1990 summary->set_out(Location::SameAsFirstInput()); | 1980 summary->set_out(Location::SameAsFirstInput()); |
| 1991 return summary; | 1981 return summary; |
| 1992 } | 1982 } |
| 1993 | 1983 |
| 1994 | 1984 |
| 1995 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1985 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1996 Register value = locs()->in(0).reg(); | 1986 Register value = locs()->in(0).reg(); |
| 1997 ASSERT(value == locs()->out().reg()); | 1987 ASSERT(value == locs()->out().reg()); |
| 1998 switch (op_kind()) { | 1988 switch (op_kind()) { |
| 1999 case Token::kNEGATE: { | 1989 case Token::kNEGATE: { |
| 2000 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 1990 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 2001 kDeoptUnaryOp); | 1991 kDeoptUnaryOp); |
| 2002 __ negq(value); | 1992 __ negq(value); |
| 2003 __ j(OVERFLOW, deopt); | 1993 __ j(OVERFLOW, deopt); |
| 2004 break; | 1994 break; |
| 2005 } | 1995 } |
| 2006 case Token::kBIT_NOT: | 1996 case Token::kBIT_NOT: |
| 2007 __ notq(value); | 1997 __ notq(value); |
| 2008 __ andq(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. | 1998 __ andq(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. |
| 2009 break; | 1999 break; |
| 2010 default: | 2000 default: |
| 2011 UNREACHABLE(); | 2001 UNREACHABLE(); |
| 2012 } | 2002 } |
| 2013 } | 2003 } |
| 2014 | 2004 |
| 2015 | 2005 |
| 2016 LocationSummary* NumberNegateComp::MakeLocationSummary() const { | 2006 LocationSummary* NumberNegateInstr::MakeLocationSummary() const { |
| 2017 const intptr_t kNumInputs = 1; | 2007 const intptr_t kNumInputs = 1; |
| 2018 const intptr_t kNumTemps = 1; // Needed for doubles. | 2008 const intptr_t kNumTemps = 1; // Needed for doubles. |
| 2019 LocationSummary* summary = | 2009 LocationSummary* summary = |
| 2020 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2010 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2021 summary->set_in(0, Location::RegisterLocation(RAX)); | 2011 summary->set_in(0, Location::RegisterLocation(RAX)); |
| 2022 summary->set_out(Location::RegisterLocation(RAX)); | 2012 summary->set_out(Location::RegisterLocation(RAX)); |
| 2023 summary->set_temp(0, Location::RegisterLocation(RCX)); | 2013 summary->set_temp(0, Location::RegisterLocation(RCX)); |
| 2024 return summary; | 2014 return summary; |
| 2025 } | 2015 } |
| 2026 | 2016 |
| 2027 | 2017 |
| 2028 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 2018 void NumberNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2029 const ICData& ic_data = *instance_call()->ic_data(); | 2019 const ICData& ic_data = *instance_call()->ic_data(); |
| 2030 ASSERT(!ic_data.IsNull()); | 2020 ASSERT(!ic_data.IsNull()); |
| 2031 ASSERT(ic_data.num_args_tested() == 1); | 2021 ASSERT(ic_data.num_args_tested() == 1); |
| 2032 | 2022 |
| 2033 // TODO(srdjan): Implement for more checks. | 2023 // TODO(srdjan): Implement for more checks. |
| 2034 ASSERT(ic_data.NumberOfChecks() == 1); | 2024 ASSERT(ic_data.NumberOfChecks() == 1); |
| 2035 intptr_t test_class_id; | 2025 intptr_t test_class_id; |
| 2036 Function& target = Function::Handle(); | 2026 Function& target = Function::Handle(); |
| 2037 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); | 2027 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); |
| 2038 | 2028 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2064 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); | 2054 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); |
| 2065 __ DoubleNegate(XMM0); | 2055 __ DoubleNegate(XMM0); |
| 2066 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 2056 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 2067 } else { | 2057 } else { |
| 2068 UNREACHABLE(); | 2058 UNREACHABLE(); |
| 2069 } | 2059 } |
| 2070 ASSERT(ResultCid() == kDoubleCid); | 2060 ASSERT(ResultCid() == kDoubleCid); |
| 2071 } | 2061 } |
| 2072 | 2062 |
| 2073 | 2063 |
| 2074 LocationSummary* DoubleToDoubleComp::MakeLocationSummary() const { | 2064 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { |
| 2075 const intptr_t kNumInputs = 1; | 2065 const intptr_t kNumInputs = 1; |
| 2076 const intptr_t kNumTemps = 0; | 2066 const intptr_t kNumTemps = 0; |
| 2077 LocationSummary* locs = | 2067 LocationSummary* locs = |
| 2078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2068 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2079 locs->set_in(0, Location::RequiresRegister()); | 2069 locs->set_in(0, Location::RequiresRegister()); |
| 2080 locs->set_out(Location::SameAsFirstInput()); | 2070 locs->set_out(Location::SameAsFirstInput()); |
| 2081 return locs; | 2071 return locs; |
| 2082 } | 2072 } |
| 2083 | 2073 |
| 2084 | 2074 |
| 2085 void DoubleToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 2075 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2086 Register value = locs()->in(0).reg(); | 2076 Register value = locs()->in(0).reg(); |
| 2087 Register result = locs()->out().reg(); | 2077 Register result = locs()->out().reg(); |
| 2088 | 2078 |
| 2089 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2079 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 2090 kDeoptDoubleToDouble); | 2080 kDeoptDoubleToDouble); |
| 2091 | 2081 |
| 2092 __ testq(value, Immediate(kSmiTagMask)); | 2082 __ testq(value, Immediate(kSmiTagMask)); |
| 2093 __ j(ZERO, deopt); // Deoptimize if Smi. | 2083 __ j(ZERO, deopt); // Deoptimize if Smi. |
| 2094 __ CompareClassId(value, kDoubleCid); | 2084 __ CompareClassId(value, kDoubleCid); |
| 2095 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. | 2085 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. |
| 2096 ASSERT(value == result); | 2086 ASSERT(value == result); |
| 2097 } | 2087 } |
| 2098 | 2088 |
| 2099 | 2089 |
| 2100 LocationSummary* SmiToDoubleComp::MakeLocationSummary() const { | 2090 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { |
| 2101 return MakeCallSummary(); // Calls a stub to allocate result. | 2091 return MakeCallSummary(); // Calls a stub to allocate result. |
| 2102 } | 2092 } |
| 2103 | 2093 |
| 2104 | 2094 |
| 2105 void SmiToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 2095 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2106 Register result = locs()->out().reg(); | 2096 Register result = locs()->out().reg(); |
| 2107 | 2097 |
| 2108 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2098 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 2109 kDeoptIntegerToDouble); | 2099 kDeoptIntegerToDouble); |
| 2110 | 2100 |
| 2111 const Class& double_class = compiler->double_class(); | 2101 const Class& double_class = compiler->double_class(); |
| 2112 const Code& stub = | 2102 const Code& stub = |
| 2113 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 2103 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 2114 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 2104 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 2115 | 2105 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2126 | 2116 |
| 2127 __ testq(value, Immediate(kSmiTagMask)); | 2117 __ testq(value, Immediate(kSmiTagMask)); |
| 2128 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. | 2118 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. |
| 2129 __ SmiUntag(value); | 2119 __ SmiUntag(value); |
| 2130 __ cvtsi2sd(XMM0, value); | 2120 __ cvtsi2sd(XMM0, value); |
| 2131 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 2121 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 2132 __ Drop(1); | 2122 __ Drop(1); |
| 2133 } | 2123 } |
| 2134 | 2124 |
| 2135 | 2125 |
| 2136 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { | 2126 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
| 2137 return MakeCallSummary(); | 2127 return MakeCallSummary(); |
| 2138 } | 2128 } |
| 2139 | 2129 |
| 2140 | 2130 |
| 2141 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 2131 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2142 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2132 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 2143 kDeoptPolymorphicInstanceCallTestFail); | 2133 kDeoptPolymorphicInstanceCallTestFail); |
| 2144 if (ic_data().NumberOfChecks() == 0) { | 2134 if (ic_data().NumberOfChecks() == 0) { |
| 2145 __ jmp(deopt); | 2135 __ jmp(deopt); |
| 2146 return; | 2136 return; |
| 2147 } | 2137 } |
| 2148 ASSERT(ic_data().num_args_tested() == 1); | 2138 ASSERT(ic_data().num_args_tested() == 1); |
| 2149 if (!with_checks()) { | 2139 if (!with_checks()) { |
| 2150 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | 2140 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
| 2151 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 2141 compiler->GenerateStaticCall(instance_call()->deopt_id(), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2170 RDI, // Class id register. | 2160 RDI, // Class id register. |
| 2171 instance_call()->ArgumentCount(), | 2161 instance_call()->ArgumentCount(), |
| 2172 instance_call()->argument_names(), | 2162 instance_call()->argument_names(), |
| 2173 deopt, | 2163 deopt, |
| 2174 instance_call()->deopt_id(), | 2164 instance_call()->deopt_id(), |
| 2175 instance_call()->token_pos(), | 2165 instance_call()->token_pos(), |
| 2176 locs()); | 2166 locs()); |
| 2177 } | 2167 } |
| 2178 | 2168 |
| 2179 | 2169 |
| 2170 LocationSummary* BranchInstr::MakeLocationSummary() const { |
| 2171 UNREACHABLE(); |
| 2172 return NULL; |
| 2173 } |
| 2174 |
| 2175 |
| 2180 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2176 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2181 computation()->EmitBranchCode(compiler, this); | 2177 comparison()->EmitBranchCode(compiler, this); |
| 2182 } | 2178 } |
| 2183 | 2179 |
| 2184 | 2180 |
| 2185 LocationSummary* CheckClassComp::MakeLocationSummary() const { | 2181 LocationSummary* CheckClassInstr::MakeLocationSummary() const { |
| 2186 const intptr_t kNumInputs = 1; | 2182 const intptr_t kNumInputs = 1; |
| 2187 const intptr_t kNumTemps = 1; | 2183 const intptr_t kNumTemps = 1; |
| 2188 LocationSummary* summary = | 2184 LocationSummary* summary = |
| 2189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2190 summary->set_in(0, Location::RequiresRegister()); | 2186 summary->set_in(0, Location::RequiresRegister()); |
| 2191 summary->set_temp(0, Location::RequiresRegister()); | 2187 summary->set_temp(0, Location::RequiresRegister()); |
| 2192 return summary; | 2188 return summary; |
| 2193 } | 2189 } |
| 2194 | 2190 |
| 2195 | 2191 |
| 2196 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 2192 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2197 Register value = locs()->in(0).reg(); | 2193 Register value = locs()->in(0).reg(); |
| 2198 Register temp = locs()->temp(0).reg(); | 2194 Register temp = locs()->temp(0).reg(); |
| 2199 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2195 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 2200 kDeoptCheckClass); | 2196 kDeoptCheckClass); |
| 2201 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid); | 2197 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid); |
| 2202 __ testq(value, Immediate(kSmiTagMask)); | 2198 __ testq(value, Immediate(kSmiTagMask)); |
| 2203 __ j(ZERO, deopt); | 2199 __ j(ZERO, deopt); |
| 2204 __ LoadClassId(temp, value); | 2200 __ LoadClassId(temp, value); |
| 2205 Label is_ok; | 2201 Label is_ok; |
| 2206 const intptr_t num_checks = unary_checks().NumberOfChecks(); | 2202 const intptr_t num_checks = unary_checks().NumberOfChecks(); |
| 2207 const bool use_near_jump = num_checks < 5; | 2203 const bool use_near_jump = num_checks < 5; |
| 2208 for (intptr_t i = 0; i < num_checks; i++) { | 2204 for (intptr_t i = 0; i < num_checks; i++) { |
| 2209 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); | 2205 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); |
| 2210 if (i == (num_checks - 1)) { | 2206 if (i == (num_checks - 1)) { |
| 2211 __ j(NOT_EQUAL, deopt); | 2207 __ j(NOT_EQUAL, deopt); |
| 2212 } else { | 2208 } else { |
| 2213 if (use_near_jump) { | 2209 if (use_near_jump) { |
| 2214 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 2210 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| 2215 } else { | 2211 } else { |
| 2216 __ j(EQUAL, &is_ok); | 2212 __ j(EQUAL, &is_ok); |
| 2217 } | 2213 } |
| 2218 } | 2214 } |
| 2219 } | 2215 } |
| 2220 __ Bind(&is_ok); | 2216 __ Bind(&is_ok); |
| 2221 } | 2217 } |
| 2222 | 2218 |
| 2223 | 2219 |
| 2224 LocationSummary* CheckSmiComp::MakeLocationSummary() const { | 2220 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { |
| 2225 const intptr_t kNumInputs = 1; | 2221 const intptr_t kNumInputs = 1; |
| 2226 const intptr_t kNumTemps = 0; | 2222 const intptr_t kNumTemps = 0; |
| 2227 LocationSummary* summary = | 2223 LocationSummary* summary = |
| 2228 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2224 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2229 summary->set_in(0, Location::RequiresRegister()); | 2225 summary->set_in(0, Location::RequiresRegister()); |
| 2230 return summary; | 2226 return summary; |
| 2231 } | 2227 } |
| 2232 | 2228 |
| 2233 | 2229 |
| 2234 void CheckSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 2230 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2235 Register value = locs()->in(0).reg(); | 2231 Register value = locs()->in(0).reg(); |
| 2236 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2232 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 2237 kDeoptCheckSmi); | 2233 kDeoptCheckSmi); |
| 2238 __ testq(value, Immediate(kSmiTagMask)); | 2234 __ testq(value, Immediate(kSmiTagMask)); |
| 2239 __ j(NOT_ZERO, deopt); | 2235 __ j(NOT_ZERO, deopt); |
| 2240 } | 2236 } |
| 2241 | 2237 |
| 2242 | 2238 |
| 2243 LocationSummary* CheckArrayBoundComp::MakeLocationSummary() const { | 2239 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { |
| 2244 const intptr_t kNumInputs = 2; | 2240 const intptr_t kNumInputs = 2; |
| 2245 const intptr_t kNumTemps = 0; | 2241 const intptr_t kNumTemps = 0; |
| 2246 LocationSummary* locs = | 2242 LocationSummary* locs = |
| 2247 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2243 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2248 locs->set_in(0, Location::RequiresRegister()); | 2244 locs->set_in(0, Location::RequiresRegister()); |
| 2249 locs->set_in(1, Location::RegisterOrConstant(index())); | 2245 locs->set_in(1, Location::RegisterOrConstant(index())); |
| 2250 return locs; | 2246 return locs; |
| 2251 } | 2247 } |
| 2252 | 2248 |
| 2253 | 2249 |
| 2254 void CheckArrayBoundComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 2250 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2255 Register receiver = locs()->in(0).reg(); | 2251 Register receiver = locs()->in(0).reg(); |
| 2256 | 2252 |
| 2257 const DeoptReasonId deopt_reason = | 2253 const DeoptReasonId deopt_reason = |
| 2258 (array_type() == kGrowableObjectArrayCid) ? | 2254 (array_type() == kGrowableObjectArrayCid) ? |
| 2259 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; | 2255 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; |
| 2260 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2256 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 2261 deopt_reason); | 2257 deopt_reason); |
| 2262 ASSERT(array_type() == kArrayCid || | 2258 ASSERT(array_type() == kArrayCid || |
| 2263 array_type() == kImmutableArrayCid || | 2259 array_type() == kImmutableArrayCid || |
| 2264 array_type() == kGrowableObjectArrayCid); | 2260 array_type() == kGrowableObjectArrayCid); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2279 __ j(ABOVE_EQUAL, deopt); | 2275 __ j(ABOVE_EQUAL, deopt); |
| 2280 } | 2276 } |
| 2281 } | 2277 } |
| 2282 | 2278 |
| 2283 | 2279 |
| 2284 } // namespace dart | 2280 } // namespace dart |
| 2285 | 2281 |
| 2286 #undef __ | 2282 #undef __ |
| 2287 | 2283 |
| 2288 #endif // defined TARGET_ARCH_X64 | 2284 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |