Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 552303005: Fix StoreIndexedInstr input representation requirements for Int32/Uint32 arrays. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix typo Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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, &not_smi);
6427 // Smi.
6428 __ movl(out, value);
6429 __ SmiTag(out);
6430 __ jmp(&done);
6431 __ Bind(&not_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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698