| OLD | NEW | 
|---|
| 1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a | 
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_IA32. | 
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) | 
| 7 | 7 | 
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" | 
| 9 | 9 | 
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" | 
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 154   if (!locs()->out(0).IsInvalid()) { | 154   if (!locs()->out(0).IsInvalid()) { | 
| 155     Register result = locs()->out(0).reg(); | 155     Register result = locs()->out(0).reg(); | 
| 156     __ LoadObjectSafely(result, value()); | 156     __ LoadObjectSafely(result, value()); | 
| 157   } | 157   } | 
| 158 } | 158 } | 
| 159 | 159 | 
| 160 | 160 | 
| 161 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate, | 161 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate, | 
| 162                                                            bool opt) const { | 162                                                            bool opt) const { | 
| 163   const intptr_t kNumInputs = 0; | 163   const intptr_t kNumInputs = 0; | 
| 164   const intptr_t kNumTemps = (constant_address() == 0) ? 1 : 0; | 164   const intptr_t kNumTemps = | 
|  | 165       (constant_address() == 0) && (representation() != kUnboxedInt32) ? 1 : 0; | 
| 165   LocationSummary* locs = new(isolate) LocationSummary( | 166   LocationSummary* locs = new(isolate) LocationSummary( | 
| 166       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 167       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 
| 167   locs->set_out(0, Location::RequiresFpuRegister()); | 168   if (representation() == kUnboxedDouble) { | 
|  | 169     locs->set_out(0, Location::RequiresFpuRegister()); | 
|  | 170   } else { | 
|  | 171     ASSERT(representation() == kUnboxedInt32); | 
|  | 172     locs->set_out(0, Location::RequiresRegister()); | 
|  | 173   } | 
| 168   if (kNumTemps == 1) { | 174   if (kNumTemps == 1) { | 
| 169     locs->set_temp(0, Location::RequiresRegister()); | 175     locs->set_temp(0, Location::RequiresRegister()); | 
| 170   } | 176   } | 
| 171   return locs; | 177   return locs; | 
| 172 } | 178 } | 
| 173 | 179 | 
| 174 | 180 | 
| 175 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 181 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 176   // The register allocator drops constant definitions that have no uses. | 182   // The register allocator drops constant definitions that have no uses. | 
| 177   if (!locs()->out(0).IsInvalid()) { | 183   if (!locs()->out(0).IsInvalid()) { | 
| (...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1214     case kOneByteStringCid: | 1220     case kOneByteStringCid: | 
| 1215     case kTypedDataInt8ArrayCid: | 1221     case kTypedDataInt8ArrayCid: | 
| 1216     case kTypedDataUint8ArrayCid: | 1222     case kTypedDataUint8ArrayCid: | 
| 1217     case kExternalTypedDataUint8ArrayCid: | 1223     case kExternalTypedDataUint8ArrayCid: | 
| 1218     case kTypedDataUint8ClampedArrayCid: | 1224     case kTypedDataUint8ClampedArrayCid: | 
| 1219     case kExternalTypedDataUint8ClampedArrayCid: | 1225     case kExternalTypedDataUint8ClampedArrayCid: | 
| 1220     case kTypedDataInt16ArrayCid: | 1226     case kTypedDataInt16ArrayCid: | 
| 1221     case kTypedDataUint16ArrayCid: | 1227     case kTypedDataUint16ArrayCid: | 
| 1222       return kTagged; | 1228       return kTagged; | 
| 1223     case kTypedDataInt32ArrayCid: | 1229     case kTypedDataInt32ArrayCid: | 
|  | 1230       return kUnboxedInt32; | 
| 1224     case kTypedDataUint32ArrayCid: | 1231     case kTypedDataUint32ArrayCid: | 
| 1225       return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1232       return kUnboxedUint32; | 
| 1226     case kTypedDataFloat32ArrayCid: | 1233     case kTypedDataFloat32ArrayCid: | 
| 1227     case kTypedDataFloat64ArrayCid: | 1234     case kTypedDataFloat64ArrayCid: | 
| 1228       return kUnboxedDouble; | 1235       return kUnboxedDouble; | 
| 1229     case kTypedDataFloat32x4ArrayCid: | 1236     case kTypedDataFloat32x4ArrayCid: | 
| 1230       return kUnboxedFloat32x4; | 1237       return kUnboxedFloat32x4; | 
| 1231     case kTypedDataInt32x4ArrayCid: | 1238     case kTypedDataInt32x4ArrayCid: | 
| 1232       return kUnboxedInt32x4; | 1239       return kUnboxedInt32x4; | 
| 1233     case kTypedDataFloat64x2ArrayCid: | 1240     case kTypedDataFloat64x2ArrayCid: | 
| 1234       return kUnboxedFloat64x2; | 1241       return kUnboxedFloat64x2; | 
| 1235     default: | 1242     default: | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1272       // EBX, ECX, EDX) instead of using a fixed register. | 1279       // EBX, ECX, EDX) instead of using a fixed register. | 
| 1273       locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); | 1280       locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); | 
| 1274       break; | 1281       break; | 
| 1275     case kTypedDataInt16ArrayCid: | 1282     case kTypedDataInt16ArrayCid: | 
| 1276     case kTypedDataUint16ArrayCid: | 1283     case kTypedDataUint16ArrayCid: | 
| 1277       // Writable register because the value must be untagged before storing. | 1284       // Writable register because the value must be untagged before storing. | 
| 1278       locs->set_in(2, Location::WritableRegister()); | 1285       locs->set_in(2, Location::WritableRegister()); | 
| 1279       break; | 1286       break; | 
| 1280     case kTypedDataInt32ArrayCid: | 1287     case kTypedDataInt32ArrayCid: | 
| 1281     case kTypedDataUint32ArrayCid: | 1288     case kTypedDataUint32ArrayCid: | 
| 1282       // For smis, use a writable register because the value must be untagged | 1289       locs->set_in(2, Location::RequiresRegister()); | 
| 1283       // before storing. Mints are stored in registers pairs. |  | 
| 1284       if (value()->IsSmiValue()) { |  | 
| 1285         locs->set_in(2, Location::WritableRegister()); |  | 
| 1286       } else { |  | 
| 1287         // We only move the lower 32-bits so we don't care where the high bits |  | 
| 1288         // are located. |  | 
| 1289         locs->set_in(2, Location::Pair(Location::RequiresRegister(), |  | 
| 1290                                        Location::Any())); |  | 
| 1291       } |  | 
| 1292       break; | 1290       break; | 
| 1293     case kTypedDataFloat32ArrayCid: | 1291     case kTypedDataFloat32ArrayCid: | 
| 1294     case kTypedDataFloat64ArrayCid: | 1292     case kTypedDataFloat64ArrayCid: | 
| 1295       // TODO(srdjan): Support Float64 constants. | 1293       // TODO(srdjan): Support Float64 constants. | 
| 1296       locs->set_in(2, Location::RequiresFpuRegister()); | 1294       locs->set_in(2, Location::RequiresFpuRegister()); | 
| 1297       break; | 1295       break; | 
| 1298     case kTypedDataInt32x4ArrayCid: | 1296     case kTypedDataInt32x4ArrayCid: | 
| 1299     case kTypedDataFloat32x4ArrayCid: | 1297     case kTypedDataFloat32x4ArrayCid: | 
| 1300     case kTypedDataFloat64x2ArrayCid: | 1298     case kTypedDataFloat64x2ArrayCid: | 
| 1301       locs->set_in(2, Location::RequiresFpuRegister()); | 1299       locs->set_in(2, Location::RequiresFpuRegister()); | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1382     } | 1380     } | 
| 1383     case kTypedDataInt16ArrayCid: | 1381     case kTypedDataInt16ArrayCid: | 
| 1384     case kTypedDataUint16ArrayCid: { | 1382     case kTypedDataUint16ArrayCid: { | 
| 1385       Register value = locs()->in(2).reg(); | 1383       Register value = locs()->in(2).reg(); | 
| 1386       __ SmiUntag(value); | 1384       __ SmiUntag(value); | 
| 1387       __ movw(element_address, value); | 1385       __ movw(element_address, value); | 
| 1388       break; | 1386       break; | 
| 1389     } | 1387     } | 
| 1390     case kTypedDataInt32ArrayCid: | 1388     case kTypedDataInt32ArrayCid: | 
| 1391     case kTypedDataUint32ArrayCid: | 1389     case kTypedDataUint32ArrayCid: | 
| 1392       if (value()->IsSmiValue()) { | 1390       __ movl(element_address, locs()->in(2).reg()); | 
| 1393         ASSERT(RequiredInputRepresentation(2) == kTagged); |  | 
| 1394         Register value = locs()->in(2).reg(); |  | 
| 1395         __ SmiUntag(value); |  | 
| 1396         __ movl(element_address, value); |  | 
| 1397       } else { |  | 
| 1398         ASSERT(RequiredInputRepresentation(2) == kUnboxedMint); |  | 
| 1399         PairLocation* value_pair = locs()->in(2).AsPairLocation(); |  | 
| 1400         Register value1 = value_pair->At(0).reg(); |  | 
| 1401         __ movl(element_address, value1); |  | 
| 1402       } |  | 
| 1403       break; | 1391       break; | 
| 1404     case kTypedDataFloat32ArrayCid: | 1392     case kTypedDataFloat32ArrayCid: | 
| 1405       __ movss(element_address, locs()->in(2).fpu_reg()); | 1393       __ movss(element_address, locs()->in(2).fpu_reg()); | 
| 1406       break; | 1394       break; | 
| 1407     case kTypedDataFloat64ArrayCid: | 1395     case kTypedDataFloat64ArrayCid: | 
| 1408       __ movsd(element_address, locs()->in(2).fpu_reg()); | 1396       __ movsd(element_address, locs()->in(2).fpu_reg()); | 
| 1409       break; | 1397       break; | 
| 1410     case kTypedDataInt32x4ArrayCid: | 1398     case kTypedDataInt32x4ArrayCid: | 
| 1411     case kTypedDataFloat32x4ArrayCid: | 1399     case kTypedDataFloat32x4ArrayCid: | 
| 1412     case kTypedDataFloat64x2ArrayCid: | 1400     case kTypedDataFloat64x2ArrayCid: | 
| (...skipping 4974 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6387 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6375 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 6388   Register out = locs()->out(0).reg(); | 6376   Register out = locs()->out(0).reg(); | 
| 6389   ASSERT(locs()->in(0).reg() == out); | 6377   ASSERT(locs()->in(0).reg() == out); | 
| 6390 | 6378 | 
| 6391   ASSERT(op_kind() == Token::kBIT_NOT); | 6379   ASSERT(op_kind() == Token::kBIT_NOT); | 
| 6392 | 6380 | 
| 6393   __ notl(out); | 6381   __ notl(out); | 
| 6394 } | 6382 } | 
| 6395 | 6383 | 
| 6396 | 6384 | 
| 6397 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, | 6385 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate, | 
| 6398                                                      bool opt) const { |  | 
| 6399   const intptr_t kNumInputs = 1; |  | 
| 6400   const intptr_t kNumTemps = 0; |  | 
| 6401   LocationSummary* summary = new(isolate) LocationSummary( |  | 
| 6402       isolate, |  | 
| 6403       kNumInputs, |  | 
| 6404       kNumTemps, |  | 
| 6405       ValueFitsSmi() ? LocationSummary::kNoCall |  | 
| 6406                      : LocationSummary::kCallOnSlowPath); |  | 
| 6407   summary->set_in(0, Location::RequiresRegister()); |  | 
| 6408   summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() |  | 
| 6409                                      : Location::RequiresRegister()); |  | 
| 6410   return summary; |  | 
| 6411 } |  | 
| 6412 |  | 
| 6413 |  | 
| 6414 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |  | 
| 6415   Register value = locs()->in(0).reg(); |  | 
| 6416   Register out = locs()->out(0).reg(); |  | 
| 6417 |  | 
| 6418   Label not_smi, done; |  | 
| 6419 |  | 
| 6420   if (ValueFitsSmi()) { |  | 
| 6421     ASSERT(value == out); |  | 
| 6422     __ SmiTag(value); |  | 
| 6423   } else { |  | 
| 6424     ASSERT(value != out); |  | 
| 6425     __ cmpl(value, Immediate(kSmiMax)); |  | 
| 6426     __ j(ABOVE, ¬_smi); |  | 
| 6427     // Smi. |  | 
| 6428     __ movl(out, value); |  | 
| 6429     __ SmiTag(out); |  | 
| 6430     __ jmp(&done); |  | 
| 6431     __ Bind(¬_smi); |  | 
| 6432     // Allocate a mint. |  | 
| 6433     BoxAllocationSlowPath::Allocate( |  | 
| 6434         compiler, this, compiler->mint_class(), out, kNoRegister); |  | 
| 6435     // Copy low word into mint. |  | 
| 6436     __ movl(FieldAddress(out, Mint::value_offset()), value); |  | 
| 6437     // Zero high word. |  | 
| 6438     __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0)); |  | 
| 6439     __ Bind(&done); |  | 
| 6440   } |  | 
| 6441 } |  | 
| 6442 |  | 
| 6443 |  | 
| 6444 LocationSummary* BoxInt32Instr::MakeLocationSummary(Isolate* isolate, |  | 
| 6445                                                     bool opt) const { | 6386                                                     bool opt) const { | 
| 6446   const intptr_t kNumInputs = 1; | 6387   const intptr_t kNumInputs = 1; | 
| 6447   const intptr_t kNumTemps = 0; | 6388   const intptr_t kNumTemps = 0; | 
| 6448   LocationSummary* summary = new(isolate) LocationSummary( | 6389   LocationSummary* summary = new(isolate) LocationSummary( | 
| 6449       isolate, kNumInputs, kNumTemps, | 6390       isolate, kNumInputs, kNumTemps, | 
| 6450       ValueFitsSmi() ? LocationSummary::kNoCall | 6391       ValueFitsSmi() ? LocationSummary::kNoCall | 
| 6451                      : LocationSummary::kCallOnSlowPath); | 6392                      : LocationSummary::kCallOnSlowPath); | 
| 6452   summary->set_in(0, ValueFitsSmi() ? Location::RequiresRegister() | 6393   const bool needs_writable_input = ValueFitsSmi() || | 
| 6453                                     : Location::WritableRegister()); | 6394       (from_representation() == kUnboxedUint32); | 
|  | 6395   summary->set_in(0, needs_writable_input ? Location::RequiresRegister() | 
|  | 6396                                           : Location::WritableRegister()); | 
| 6454   summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() | 6397   summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() | 
| 6455                                      : Location::RequiresRegister()); | 6398                                      : Location::RequiresRegister()); | 
| 6456   return summary; | 6399   return summary; | 
| 6457 } | 6400 } | 
| 6458 | 6401 | 
| 6459 | 6402 | 
| 6460 void BoxInt32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6403 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 6461   Register value = locs()->in(0).reg(); | 6404   const Register value = locs()->in(0).reg(); | 
| 6462   Register out = locs()->out(0).reg(); | 6405   const Register out = locs()->out(0).reg(); | 
| 6463 | 6406 | 
| 6464   if (out != value) { | 6407   __ MoveRegister(out, value); | 
| 6465     __ movl(out, value); | 6408   __ shll(out, Immediate(kSmiTagSize)); | 
| 6466   } |  | 
| 6467   __ shll(out, Immediate(1)); |  | 
| 6468   if (!ValueFitsSmi()) { | 6409   if (!ValueFitsSmi()) { | 
| 6469     Label done; | 6410     Label done; | 
| 6470     __ j(NO_OVERFLOW, &done); | 6411     ASSERT(value != out); | 
|  | 6412     if (from_representation() == kUnboxedInt32) { | 
|  | 6413       __ j(NO_OVERFLOW, &done); | 
|  | 6414     } else { | 
|  | 6415       __ testl(value, Immediate(0xC0000000)); | 
|  | 6416       __ j(ZERO, &done); | 
|  | 6417     } | 
|  | 6418 | 
| 6471     // Allocate a mint. | 6419     // Allocate a mint. | 
| 6472     // Value input is writable register and has to be manually preserved | 6420     // Value input is writable register and has to be manually preserved | 
| 6473     // on the slow path. | 6421     // on the slow path. | 
| 6474     locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32); | 6422     locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32); | 
| 6475     BoxAllocationSlowPath::Allocate( | 6423     BoxAllocationSlowPath::Allocate( | 
| 6476         compiler, this, compiler->mint_class(), out, kNoRegister); | 6424         compiler, this, compiler->mint_class(), out, kNoRegister); | 
| 6477     __ movl(FieldAddress(out, Mint::value_offset()), value); | 6425     __ movl(FieldAddress(out, Mint::value_offset()), value); | 
| 6478     __ sarl(value, Immediate(31));  // Sign extend. | 6426     if (from_representation() == kUnboxedInt32) { | 
| 6479     __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value); | 6427       __ sarl(value, Immediate(31));  // Sign extend. | 
|  | 6428       __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value); | 
|  | 6429     } else { | 
|  | 6430       __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), | 
|  | 6431               Immediate(0)); | 
|  | 6432     } | 
| 6480     __ Bind(&done); | 6433     __ Bind(&done); | 
| 6481   } | 6434   } | 
| 6482 } | 6435 } | 
| 6483 | 6436 | 
| 6484 | 6437 | 
| 6485 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, | 6438 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate, | 
| 6486                                                        bool opt) const { | 6439                                                        bool opt) const { | 
| 6487   const intptr_t value_cid = value()->Type()->ToCid(); | 6440   const intptr_t value_cid = value()->Type()->ToCid(); | 
| 6488   const intptr_t kNumInputs = 1; | 6441   const intptr_t kNumInputs = 1; | 
| 6489   const intptr_t kNumTemps = | 6442   intptr_t kNumTemps = 0; | 
| 6490       ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1; | 6443 | 
|  | 6444   if (CanDeoptimize()) { | 
|  | 6445     if ((value_cid != kSmiCid) && | 
|  | 6446         (value_cid != kMintCid) && | 
|  | 6447         !is_truncating()) { | 
|  | 6448       kNumTemps = 2; | 
|  | 6449     } else { | 
|  | 6450       kNumTemps = 1; | 
|  | 6451     } | 
|  | 6452   } | 
|  | 6453 | 
| 6491   LocationSummary* summary = new(isolate) LocationSummary( | 6454   LocationSummary* summary = new(isolate) LocationSummary( | 
| 6492       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6455       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 
| 6493   summary->set_in(0, Location::RequiresRegister()); | 6456   summary->set_in(0, Location::RequiresRegister()); | 
| 6494   if (kNumTemps > 0) { | 6457   for (int i = 0; i < kNumTemps; i++) { | 
| 6495     summary->set_temp(0, Location::RequiresRegister()); | 6458     summary->set_temp(i, Location::RequiresRegister()); | 
| 6496   } | 6459   } | 
| 6497   summary->set_out(0, Location::SameAsFirstInput()); | 6460   summary->set_out(0, ((value_cid == kSmiCid) || (value_cid != kMintCid)) ? | 
| 6498   return summary; | 6461       Location::SameAsFirstInput() : Location::RequiresRegister()); | 
| 6499 } |  | 
| 6500 |  | 
| 6501 |  | 
| 6502 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |  | 
| 6503   const intptr_t value_cid = value()->Type()->ToCid(); |  | 
| 6504   const Register value = locs()->in(0).reg(); |  | 
| 6505   ASSERT(value == locs()->out(0).reg()); |  | 
| 6506 |  | 
| 6507   // TODO(johnmccutchan): Emit better code for constant inputs. |  | 
| 6508   if (value_cid == kMintCid) { |  | 
| 6509     __ movl(value, FieldAddress(value, Mint::value_offset())); |  | 
| 6510   } else if (value_cid == kSmiCid) { |  | 
| 6511     __ SmiUntag(value); |  | 
| 6512   } else { |  | 
| 6513     Register temp = locs()->temp(0).reg(); |  | 
| 6514     Label* deopt = compiler->AddDeoptStub(deopt_id_, |  | 
| 6515                                           ICData::kDeoptUnboxInteger); |  | 
| 6516     Label is_smi, done; |  | 
| 6517     __ testl(value, Immediate(kSmiTagMask)); |  | 
| 6518     __ j(ZERO, &is_smi); |  | 
| 6519     __ CompareClassId(value, kMintCid, temp); |  | 
| 6520     __ j(NOT_EQUAL, deopt); |  | 
| 6521     __ movl(value, FieldAddress(value, Mint::value_offset())); |  | 
| 6522     __ jmp(&done); |  | 
| 6523     __ Bind(&is_smi); |  | 
| 6524     __ SmiUntag(value); |  | 
| 6525     __ Bind(&done); |  | 
| 6526   } |  | 
| 6527 } |  | 
| 6528 |  | 
| 6529 |  | 
| 6530 LocationSummary* UnboxInt32Instr::MakeLocationSummary(Isolate* isolate, |  | 
| 6531                                                        bool opt) const { |  | 
| 6532   const intptr_t value_cid = value()->Type()->ToCid(); |  | 
| 6533   const intptr_t kNumInputs = 1; |  | 
| 6534   const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; |  | 
| 6535   LocationSummary* summary = new(isolate) LocationSummary( |  | 
| 6536       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |  | 
| 6537   summary->set_in(0, Location::RequiresRegister()); |  | 
| 6538   if (kNumTemps > 0) { |  | 
| 6539     summary->set_temp(0, Location::RequiresRegister()); |  | 
| 6540   } |  | 
| 6541   summary->set_out(0, (value_cid == kSmiCid) ? Location::SameAsFirstInput() |  | 
| 6542                                              : Location::RequiresRegister()); |  | 
| 6543   return summary; | 6462   return summary; | 
| 6544 } | 6463 } | 
| 6545 | 6464 | 
| 6546 | 6465 | 
| 6547 static void LoadInt32FromMint(FlowGraphCompiler* compiler, | 6466 static void LoadInt32FromMint(FlowGraphCompiler* compiler, | 
| 6548                               Register mint, |  | 
| 6549                               Register result, | 6467                               Register result, | 
|  | 6468                               const Address& lo, | 
|  | 6469                               const Address& hi, | 
| 6550                               Register temp, | 6470                               Register temp, | 
| 6551                               Label* deopt) { | 6471                               Label* deopt) { | 
| 6552   __ movl(result, FieldAddress(mint, Mint::value_offset())); | 6472   __ movl(result, lo); | 
| 6553   if (deopt != NULL) { | 6473   if (deopt != NULL) { | 
|  | 6474     ASSERT(temp != result); | 
| 6554     __ movl(temp, result); | 6475     __ movl(temp, result); | 
| 6555     __ sarl(temp, Immediate(31)); | 6476     __ sarl(temp, Immediate(31)); | 
| 6556     __ cmpl(temp, FieldAddress(mint, Mint::value_offset() + kWordSize)); | 6477     __ cmpl(temp, hi); | 
| 6557     __ j(NOT_EQUAL, deopt); | 6478     __ j(NOT_EQUAL, deopt); | 
| 6558   } | 6479   } | 
| 6559 } | 6480 } | 
| 6560 | 6481 | 
| 6561 | 6482 | 
| 6562 void UnboxInt32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6483 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 6563   const intptr_t value_cid = value()->Type()->ToCid(); | 6484   const intptr_t value_cid = value()->Type()->ToCid(); | 
| 6564   const Register value = locs()->in(0).reg(); | 6485   Register value = locs()->in(0).reg(); | 
| 6565   const Register result = locs()->out(0).reg(); | 6486   const Register result = locs()->out(0).reg(); | 
|  | 6487   const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; | 
|  | 6488   Label* deopt = CanDeoptimize() ? | 
|  | 6489       compiler->AddDeoptStub(deopt_id_, ICData::kDeoptUnboxInteger) : NULL; | 
|  | 6490   Label* out_of_range = !is_truncating() ? deopt : NULL; | 
| 6566 | 6491 | 
| 6567   // TODO(johnmccutchan): Emit better code for constant inputs. | 6492   const intptr_t lo_offset = Mint::value_offset(); | 
| 6568   if (value_cid == kMintCid) { | 6493   const intptr_t hi_offset = Mint::value_offset() + kWordSize; | 
| 6569     Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; | 6494 | 
| 6570     Label* deopt = CanDeoptimize() ? | 6495   if (value_cid == kSmiCid) { | 
| 6571         compiler->AddDeoptStub(deopt_id_, ICData::kDeoptUnboxInteger) : NULL; |  | 
| 6572     LoadInt32FromMint(compiler, |  | 
| 6573                       value, |  | 
| 6574                       result, |  | 
| 6575                       temp, |  | 
| 6576                       deopt); |  | 
| 6577   } else if (value_cid == kSmiCid) { |  | 
| 6578     ASSERT(value == result); | 6496     ASSERT(value == result); | 
| 6579     __ SmiUntag(value); | 6497     __ SmiUntag(value); | 
|  | 6498   } else if (value_cid == kMintCid) { | 
|  | 6499     ASSERT((value != result) || (out_of_range == NULL)); | 
|  | 6500     LoadInt32FromMint(compiler, | 
|  | 6501                       result, | 
|  | 6502                       FieldAddress(value, lo_offset), | 
|  | 6503                       FieldAddress(value, hi_offset), | 
|  | 6504                       temp, | 
|  | 6505                       out_of_range); | 
| 6580   } else { | 6506   } else { | 
| 6581     Register temp = locs()->temp(0).reg(); | 6507     ASSERT(value == result); | 
| 6582     Label* deopt = compiler->AddDeoptStub(deopt_id_, | 6508     Label done; | 
| 6583                                           ICData::kDeoptUnboxInteger); | 6509     __ SmiUntagOrCheckClass(value, kMintCid, temp, &done); | 
| 6584     Label is_smi, done; |  | 
| 6585     __ testl(value, Immediate(kSmiTagMask)); |  | 
| 6586     __ j(ZERO, &is_smi); |  | 
| 6587     __ CompareClassId(value, kMintCid, temp); |  | 
| 6588     __ j(NOT_EQUAL, deopt); | 6510     __ j(NOT_EQUAL, deopt); | 
|  | 6511     if (out_of_range != NULL) { | 
|  | 6512       Register value_temp = locs()->temp(1).reg(); | 
|  | 6513       __ movl(value_temp, value); | 
|  | 6514       value = value_temp; | 
|  | 6515     } | 
| 6589     LoadInt32FromMint(compiler, | 6516     LoadInt32FromMint(compiler, | 
| 6590                       value, |  | 
| 6591                       result, | 6517                       result, | 
|  | 6518                       Address(value, TIMES_2, lo_offset), | 
|  | 6519                       Address(value, TIMES_2, hi_offset), | 
| 6592                       temp, | 6520                       temp, | 
| 6593                       deopt); | 6521                       out_of_range); | 
| 6594     __ movl(value, FieldAddress(value, Mint::value_offset())); |  | 
| 6595     __ jmp(&done); |  | 
| 6596     __ Bind(&is_smi); |  | 
| 6597     __ SmiUntag(value); |  | 
| 6598     __ Bind(&done); | 6522     __ Bind(&done); | 
| 6599   } | 6523   } | 
| 6600 } | 6524 } | 
| 6601 | 6525 | 
| 6602 | 6526 | 
| 6603 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | 6527 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | 
| 6604                                                                bool opt) const { | 6528                                                                bool opt) const { | 
| 6605   const intptr_t kNumInputs = 1; | 6529   const intptr_t kNumInputs = 1; | 
| 6606   const intptr_t kNumTemps = 0; | 6530   const intptr_t kNumTemps = 0; | 
| 6607   LocationSummary* summary = new(isolate) LocationSummary( | 6531   LocationSummary* summary = new(isolate) LocationSummary( | 
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 7037   __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6961   __ movl(EDX, Immediate(kInvalidObjectPointer)); | 
| 7038   __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6962   __ movl(EDX, Immediate(kInvalidObjectPointer)); | 
| 7039 #endif | 6963 #endif | 
| 7040 } | 6964 } | 
| 7041 | 6965 | 
| 7042 }  // namespace dart | 6966 }  // namespace dart | 
| 7043 | 6967 | 
| 7044 #undef __ | 6968 #undef __ | 
| 7045 | 6969 | 
| 7046 #endif  // defined TARGET_ARCH_IA32 | 6970 #endif  // defined TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|