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