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

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

Issue 254723003: Remember all deopt reasons in ic_data, not just the last one. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 } 595 }
596 596
597 597
598 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 598 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
599 BranchLabels labels) { 599 BranchLabels labels) {
600 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); 600 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
601 Register val_reg = locs()->in(0).reg(); 601 Register val_reg = locs()->in(0).reg();
602 Register cid_reg = locs()->temp(0).reg(); 602 Register cid_reg = locs()->temp(0).reg();
603 603
604 Label* deopt = CanDeoptimize() ? 604 Label* deopt = CanDeoptimize() ?
605 compiler->AddDeoptStub(deopt_id(), kDeoptTestCids) : NULL; 605 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL;
606 606
607 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; 607 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
608 const ZoneGrowableArray<intptr_t>& data = cid_results(); 608 const ZoneGrowableArray<intptr_t>& data = cid_results();
609 ASSERT(data[0] == kSmiCid); 609 ASSERT(data[0] == kSmiCid);
610 bool result = data[1] == true_result; 610 bool result = data[1] == true_result;
611 __ testl(val_reg, Immediate(kSmiTagMask)); 611 __ testl(val_reg, Immediate(kSmiTagMask));
612 __ j(ZERO, result ? labels.true_label : labels.false_label); 612 __ j(ZERO, result ? labels.true_label : labels.false_label);
613 __ LoadClassId(cid_reg, val_reg); 613 __ LoadClassId(cid_reg, val_reg);
614 for (intptr_t i = 2; i < data.length(); i += 2) { 614 for (intptr_t i = 2; i < data.length(); i += 2) {
615 const intptr_t test_cid = data[i]; 615 const intptr_t test_cid = data[i];
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 case kTypedDataInt16ArrayCid: 1073 case kTypedDataInt16ArrayCid:
1074 __ movsxw(result, element_address); 1074 __ movsxw(result, element_address);
1075 __ SmiTag(result); 1075 __ SmiTag(result);
1076 break; 1076 break;
1077 case kTypedDataUint16ArrayCid: 1077 case kTypedDataUint16ArrayCid:
1078 case kTwoByteStringCid: 1078 case kTwoByteStringCid:
1079 __ movzxw(result, element_address); 1079 __ movzxw(result, element_address);
1080 __ SmiTag(result); 1080 __ SmiTag(result);
1081 break; 1081 break;
1082 case kTypedDataInt32ArrayCid: { 1082 case kTypedDataInt32ArrayCid: {
1083 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load); 1083 Label* deopt = compiler->AddDeoptStub(deopt_id(),
1084 ICData::kDeoptInt32Load);
1084 __ movl(result, element_address); 1085 __ movl(result, element_address);
1085 // Verify that the signed value in 'result' can fit inside a Smi. 1086 // Verify that the signed value in 'result' can fit inside a Smi.
1086 __ cmpl(result, Immediate(0xC0000000)); 1087 __ cmpl(result, Immediate(0xC0000000));
1087 __ j(NEGATIVE, deopt); 1088 __ j(NEGATIVE, deopt);
1088 __ SmiTag(result); 1089 __ SmiTag(result);
1089 } 1090 }
1090 break; 1091 break;
1091 case kTypedDataUint32ArrayCid: { 1092 case kTypedDataUint32ArrayCid: {
1092 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load); 1093 Label* deopt = compiler->AddDeoptStub(deopt_id(),
1094 ICData::kDeoptUint32Load);
1093 __ movl(result, element_address); 1095 __ movl(result, element_address);
1094 // Verify that the unsigned value in 'result' can fit inside a Smi. 1096 // Verify that the unsigned value in 'result' can fit inside a Smi.
1095 __ testl(result, Immediate(0xC0000000)); 1097 __ testl(result, Immediate(0xC0000000));
1096 __ j(NOT_ZERO, deopt); 1098 __ j(NOT_ZERO, deopt);
1097 __ SmiTag(result); 1099 __ SmiTag(result);
1098 } 1100 }
1099 break; 1101 break;
1100 default: 1102 default:
1101 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1103 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1102 __ movl(result, element_address); 1104 __ movl(result, element_address);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 1369
1368 Register value_cid_reg = needs_value_temp_reg ? 1370 Register value_cid_reg = needs_value_temp_reg ?
1369 locs()->temp(0).reg() : kNoRegister; 1371 locs()->temp(0).reg() : kNoRegister;
1370 1372
1371 Register field_reg = needs_field_temp_reg ? 1373 Register field_reg = needs_field_temp_reg ?
1372 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; 1374 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister;
1373 1375
1374 Label ok, fail_label; 1376 Label ok, fail_label;
1375 1377
1376 Label* deopt = compiler->is_optimizing() ? 1378 Label* deopt = compiler->is_optimizing() ?
1377 compiler->AddDeoptStub(deopt_id(), kDeoptGuardField) : NULL; 1379 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField) : NULL;
1378 1380
1379 Label* fail = (deopt != NULL) ? deopt : &fail_label; 1381 Label* fail = (deopt != NULL) ? deopt : &fail_label;
1380 1382
1381 if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) { 1383 if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) {
1382 if (!compiler->is_optimizing() && (field_reg == kNoRegister)) { 1384 if (!compiler->is_optimizing() && (field_reg == kNoRegister)) {
1383 // Currently we can't have different location summaries for optimized 1385 // Currently we can't have different location summaries for optimized
1384 // and non-optimized code. So instead we manually pick up a register 1386 // and non-optimized code. So instead we manually pick up a register
1385 // that is known to be free because we know how non-optimizing compiler 1387 // that is known to be free because we know how non-optimizing compiler
1386 // allocates registers. 1388 // allocates registers.
1387 field_reg = EBX; 1389 field_reg = EBX;
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after
2679 2681
2680 2682
2681 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, 2683 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
2682 BinarySmiOpInstr* shift_left) { 2684 BinarySmiOpInstr* shift_left) {
2683 const bool is_truncating = shift_left->is_truncating(); 2685 const bool is_truncating = shift_left->is_truncating();
2684 const LocationSummary& locs = *shift_left->locs(); 2686 const LocationSummary& locs = *shift_left->locs();
2685 Register left = locs.in(0).reg(); 2687 Register left = locs.in(0).reg();
2686 Register result = locs.out(0).reg(); 2688 Register result = locs.out(0).reg();
2687 ASSERT(left == result); 2689 ASSERT(left == result);
2688 Label* deopt = shift_left->CanDeoptimize() ? 2690 Label* deopt = shift_left->CanDeoptimize() ?
2689 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; 2691 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp)
2692 : NULL;
2690 if (locs.in(1).IsConstant()) { 2693 if (locs.in(1).IsConstant()) {
2691 const Object& constant = locs.in(1).constant(); 2694 const Object& constant = locs.in(1).constant();
2692 ASSERT(constant.IsSmi()); 2695 ASSERT(constant.IsSmi());
2693 // shll operation masks the count to 5 bits. 2696 // shll operation masks the count to 5 bits.
2694 const intptr_t kCountLimit = 0x1F; 2697 const intptr_t kCountLimit = 0x1F;
2695 const intptr_t value = Smi::Cast(constant).Value(); 2698 const intptr_t value = Smi::Cast(constant).Value();
2696 if (value == 0) { 2699 if (value == 0) {
2697 // No code needed. 2700 // No code needed.
2698 } else if ((value < 0) || (value >= kCountLimit)) { 2701 } else if ((value < 0) || (value >= kCountLimit)) {
2699 // This condition may not be known earlier in some cases because 2702 // This condition may not be known earlier in some cases because
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2873 EmitSmiShiftLeft(compiler, this); 2876 EmitSmiShiftLeft(compiler, this);
2874 return; 2877 return;
2875 } 2878 }
2876 2879
2877 ASSERT(!is_truncating()); 2880 ASSERT(!is_truncating());
2878 Register left = locs()->in(0).reg(); 2881 Register left = locs()->in(0).reg();
2879 Register result = locs()->out(0).reg(); 2882 Register result = locs()->out(0).reg();
2880 ASSERT(left == result); 2883 ASSERT(left == result);
2881 Label* deopt = NULL; 2884 Label* deopt = NULL;
2882 if (CanDeoptimize()) { 2885 if (CanDeoptimize()) {
2883 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 2886 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp);
2884 } 2887 }
2885 2888
2886 if (locs()->in(1).IsConstant()) { 2889 if (locs()->in(1).IsConstant()) {
2887 const Object& constant = locs()->in(1).constant(); 2890 const Object& constant = locs()->in(1).constant();
2888 ASSERT(constant.IsSmi()); 2891 ASSERT(constant.IsSmi());
2889 const int32_t imm = 2892 const int32_t imm =
2890 reinterpret_cast<int32_t>(constant.raw()); 2893 reinterpret_cast<int32_t>(constant.raw());
2891 switch (op_kind()) { 2894 switch (op_kind()) {
2892 case Token::kADD: 2895 case Token::kADD:
2893 __ addl(left, Immediate(imm)); 2896 __ addl(left, Immediate(imm));
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
3179 LocationSummary* summary = 3182 LocationSummary* summary =
3180 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3183 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3181 summary->set_in(0, Location::RequiresRegister()); 3184 summary->set_in(0, Location::RequiresRegister());
3182 summary->set_in(1, Location::RequiresRegister()); 3185 summary->set_in(1, Location::RequiresRegister());
3183 if (need_temp) summary->set_temp(0, Location::RequiresRegister()); 3186 if (need_temp) summary->set_temp(0, Location::RequiresRegister());
3184 return summary; 3187 return summary;
3185 } 3188 }
3186 3189
3187 3190
3188 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3191 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3189 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryDoubleOp); 3192 Label* deopt = compiler->AddDeoptStub(deopt_id(),
3193 ICData::kDeoptBinaryDoubleOp);
3190 intptr_t left_cid = left()->Type()->ToCid(); 3194 intptr_t left_cid = left()->Type()->ToCid();
3191 intptr_t right_cid = right()->Type()->ToCid(); 3195 intptr_t right_cid = right()->Type()->ToCid();
3192 Register left = locs()->in(0).reg(); 3196 Register left = locs()->in(0).reg();
3193 Register right = locs()->in(1).reg(); 3197 Register right = locs()->in(1).reg();
3194 if (left_cid == kSmiCid) { 3198 if (left_cid == kSmiCid) {
3195 __ testl(right, Immediate(kSmiTagMask)); 3199 __ testl(right, Immediate(kSmiTagMask));
3196 } else if (right_cid == kSmiCid) { 3200 } else if (right_cid == kSmiCid) {
3197 __ testl(left, Immediate(kSmiTagMask)); 3201 __ testl(left, Immediate(kSmiTagMask));
3198 } else { 3202 } else {
3199 Register temp = locs()->temp(0).reg(); 3203 Register temp = locs()->temp(0).reg();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3259 const intptr_t value_cid = value()->Type()->ToCid(); 3263 const intptr_t value_cid = value()->Type()->ToCid();
3260 const Register value = locs()->in(0).reg(); 3264 const Register value = locs()->in(0).reg();
3261 const XmmRegister result = locs()->out(0).fpu_reg(); 3265 const XmmRegister result = locs()->out(0).fpu_reg();
3262 3266
3263 if (value_cid == kDoubleCid) { 3267 if (value_cid == kDoubleCid) {
3264 __ movsd(result, FieldAddress(value, Double::value_offset())); 3268 __ movsd(result, FieldAddress(value, Double::value_offset()));
3265 } else if (value_cid == kSmiCid) { 3269 } else if (value_cid == kSmiCid) {
3266 __ SmiUntag(value); // Untag input before conversion. 3270 __ SmiUntag(value); // Untag input before conversion.
3267 __ cvtsi2sd(result, value); 3271 __ cvtsi2sd(result, value);
3268 } else { 3272 } else {
3269 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); 3273 Label* deopt = compiler->AddDeoptStub(deopt_id_,
3274 ICData::kDeoptBinaryDoubleOp);
3270 Register temp = locs()->temp(0).reg(); 3275 Register temp = locs()->temp(0).reg();
3271 Label is_smi, done; 3276 Label is_smi, done;
3272 __ testl(value, Immediate(kSmiTagMask)); 3277 __ testl(value, Immediate(kSmiTagMask));
3273 __ j(ZERO, &is_smi); 3278 __ j(ZERO, &is_smi);
3274 __ CompareClassId(value, kDoubleCid, temp); 3279 __ CompareClassId(value, kDoubleCid, temp);
3275 __ j(NOT_EQUAL, deopt); 3280 __ j(NOT_EQUAL, deopt);
3276 __ movsd(result, FieldAddress(value, Double::value_offset())); 3281 __ movsd(result, FieldAddress(value, Double::value_offset()));
3277 __ jmp(&done); 3282 __ jmp(&done);
3278 __ Bind(&is_smi); 3283 __ Bind(&is_smi);
3279 __ movl(temp, value); 3284 __ movl(temp, value);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3330 } 3335 }
3331 3336
3332 3337
3333 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3338 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3334 const intptr_t value_cid = value()->Type()->ToCid(); 3339 const intptr_t value_cid = value()->Type()->ToCid();
3335 const Register value = locs()->in(0).reg(); 3340 const Register value = locs()->in(0).reg();
3336 const XmmRegister result = locs()->out(0).fpu_reg(); 3341 const XmmRegister result = locs()->out(0).fpu_reg();
3337 3342
3338 if (value_cid != kFloat32x4Cid) { 3343 if (value_cid != kFloat32x4Cid) {
3339 const Register temp = locs()->temp(0).reg(); 3344 const Register temp = locs()->temp(0).reg();
3340 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3345 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass);
3341 __ testl(value, Immediate(kSmiTagMask)); 3346 __ testl(value, Immediate(kSmiTagMask));
3342 __ j(ZERO, deopt); 3347 __ j(ZERO, deopt);
3343 __ CompareClassId(value, kFloat32x4Cid, temp); 3348 __ CompareClassId(value, kFloat32x4Cid, temp);
3344 __ j(NOT_EQUAL, deopt); 3349 __ j(NOT_EQUAL, deopt);
3345 } 3350 }
3346 __ movups(result, FieldAddress(value, Float32x4::value_offset())); 3351 __ movups(result, FieldAddress(value, Float32x4::value_offset()));
3347 } 3352 }
3348 3353
3349 3354
3350 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { 3355 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3393 } 3398 }
3394 3399
3395 3400
3396 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3401 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3397 const intptr_t value_cid = value()->Type()->ToCid(); 3402 const intptr_t value_cid = value()->Type()->ToCid();
3398 const Register value = locs()->in(0).reg(); 3403 const Register value = locs()->in(0).reg();
3399 const XmmRegister result = locs()->out(0).fpu_reg(); 3404 const XmmRegister result = locs()->out(0).fpu_reg();
3400 3405
3401 if (value_cid != kFloat64x2Cid) { 3406 if (value_cid != kFloat64x2Cid) {
3402 const Register temp = locs()->temp(0).reg(); 3407 const Register temp = locs()->temp(0).reg();
3403 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3408 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass);
3404 __ testl(value, Immediate(kSmiTagMask)); 3409 __ testl(value, Immediate(kSmiTagMask));
3405 __ j(ZERO, deopt); 3410 __ j(ZERO, deopt);
3406 __ CompareClassId(value, kFloat64x2Cid, temp); 3411 __ CompareClassId(value, kFloat64x2Cid, temp);
3407 __ j(NOT_EQUAL, deopt); 3412 __ j(NOT_EQUAL, deopt);
3408 } 3413 }
3409 __ movups(result, FieldAddress(value, Float64x2::value_offset())); 3414 __ movups(result, FieldAddress(value, Float64x2::value_offset()));
3410 } 3415 }
3411 3416
3412 3417
3413 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { 3418 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
3488 } 3493 }
3489 3494
3490 3495
3491 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3496 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3492 const intptr_t value_cid = value()->Type()->ToCid(); 3497 const intptr_t value_cid = value()->Type()->ToCid();
3493 const Register value = locs()->in(0).reg(); 3498 const Register value = locs()->in(0).reg();
3494 const XmmRegister result = locs()->out(0).fpu_reg(); 3499 const XmmRegister result = locs()->out(0).fpu_reg();
3495 3500
3496 if (value_cid != kInt32x4Cid) { 3501 if (value_cid != kInt32x4Cid) {
3497 const Register temp = locs()->temp(0).reg(); 3502 const Register temp = locs()->temp(0).reg();
3498 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3503 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass);
3499 __ testl(value, Immediate(kSmiTagMask)); 3504 __ testl(value, Immediate(kSmiTagMask));
3500 __ j(ZERO, deopt); 3505 __ j(ZERO, deopt);
3501 __ CompareClassId(value, kInt32x4Cid, temp); 3506 __ CompareClassId(value, kInt32x4Cid, temp);
3502 __ j(NOT_EQUAL, deopt); 3507 __ j(NOT_EQUAL, deopt);
3503 } 3508 }
3504 __ movups(result, FieldAddress(value, Int32x4::value_offset())); 3509 __ movups(result, FieldAddress(value, Int32x4::value_offset()));
3505 } 3510 }
3506 3511
3507 3512
3508 3513
(...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after
4631 Location::SameAsFirstInput(), 4636 Location::SameAsFirstInput(),
4632 LocationSummary::kNoCall); 4637 LocationSummary::kNoCall);
4633 } 4638 }
4634 4639
4635 4640
4636 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4641 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4637 Register value = locs()->in(0).reg(); 4642 Register value = locs()->in(0).reg();
4638 ASSERT(value == locs()->out(0).reg()); 4643 ASSERT(value == locs()->out(0).reg());
4639 switch (op_kind()) { 4644 switch (op_kind()) {
4640 case Token::kNEGATE: { 4645 case Token::kNEGATE: {
4641 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4646 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp);
4642 kDeoptUnaryOp);
4643 __ negl(value); 4647 __ negl(value);
4644 __ j(OVERFLOW, deopt); 4648 __ j(OVERFLOW, deopt);
4645 break; 4649 break;
4646 } 4650 }
4647 case Token::kBIT_NOT: 4651 case Token::kBIT_NOT:
4648 __ notl(value); 4652 __ notl(value);
4649 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 4653 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
4650 break; 4654 break;
4651 default: 4655 default:
4652 UNREACHABLE(); 4656 UNREACHABLE();
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
4740 const intptr_t kNumTemps = 0; 4744 const intptr_t kNumTemps = 0;
4741 LocationSummary* result = new LocationSummary( 4745 LocationSummary* result = new LocationSummary(
4742 kNumInputs, kNumTemps, LocationSummary::kNoCall); 4746 kNumInputs, kNumTemps, LocationSummary::kNoCall);
4743 result->set_in(0, Location::RequiresFpuRegister()); 4747 result->set_in(0, Location::RequiresFpuRegister());
4744 result->set_out(0, Location::RequiresRegister()); 4748 result->set_out(0, Location::RequiresRegister());
4745 return result; 4749 return result;
4746 } 4750 }
4747 4751
4748 4752
4749 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4753 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4750 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); 4754 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptDoubleToSmi);
4751 Register result = locs()->out(0).reg(); 4755 Register result = locs()->out(0).reg();
4752 XmmRegister value = locs()->in(0).fpu_reg(); 4756 XmmRegister value = locs()->in(0).fpu_reg();
4753 __ cvttsd2si(result, value); 4757 __ cvttsd2si(result, value);
4754 // Check for overflow and that it fits into Smi. 4758 // Check for overflow and that it fits into Smi.
4755 __ cmpl(result, Immediate(0xC0000000)); 4759 __ cmpl(result, Immediate(0xC0000000));
4756 __ j(NEGATIVE, deopt); 4760 __ j(NEGATIVE, deopt);
4757 __ SmiTag(result); 4761 __ SmiTag(result);
4758 } 4762 }
4759 4763
4760 4764
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
5015 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); 5019 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos);
5016 5020
5017 extern const RuntimeEntry kSinCosRuntimeEntry( 5021 extern const RuntimeEntry kSinCosRuntimeEntry(
5018 "libc_sincos", reinterpret_cast<RuntimeFunction>( 5022 "libc_sincos", reinterpret_cast<RuntimeFunction>(
5019 static_cast<SinCosCFunction>(&SinCos)), 1, true, true); 5023 static_cast<SinCosCFunction>(&SinCos)), 1, true, true);
5020 5024
5021 5025
5022 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5026 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5023 Label* deopt = NULL; 5027 Label* deopt = NULL;
5024 if (CanDeoptimize()) { 5028 if (CanDeoptimize()) {
5025 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 5029 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp);
5026 } 5030 }
5027 5031
5028 if (kind() == MergedMathInstr::kTruncDivMod) { 5032 if (kind() == MergedMathInstr::kTruncDivMod) {
5029 Register left = locs()->in(0).reg(); 5033 Register left = locs()->in(0).reg();
5030 Register right = locs()->in(1).reg(); 5034 Register right = locs()->in(1).reg();
5031 ASSERT(locs()->out(0).IsPairLocation()); 5035 ASSERT(locs()->out(0).IsPairLocation());
5032 PairLocation* pair = locs()->out(0).AsPairLocation(); 5036 PairLocation* pair = locs()->out(0).AsPairLocation();
5033 Register result1 = pair->At(0).reg(); 5037 Register result1 = pair->At(0).reg();
5034 Register result2 = pair->At(1).reg(); 5038 Register result2 = pair->At(1).reg();
5035 Range* right_range = InputAt(1)->definition()->range(); 5039 Range* right_range = InputAt(1)->definition()->range();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
5114 } 5118 }
5115 5119
5116 5120
5117 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( 5121 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
5118 bool opt) const { 5122 bool opt) const {
5119 return MakeCallSummary(); 5123 return MakeCallSummary();
5120 } 5124 }
5121 5125
5122 5126
5123 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5127 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5124 Label* deopt = compiler->AddDeoptStub(deopt_id(), 5128 Label* deopt = compiler->AddDeoptStub(
5125 kDeoptPolymorphicInstanceCallTestFail); 5129 deopt_id(), ICData::kDeoptPolymorphicInstanceCallTestFail);
5126 if (ic_data().NumberOfChecks() == 0) { 5130 if (ic_data().NumberOfChecks() == 0) {
5127 __ jmp(deopt); 5131 __ jmp(deopt);
5128 return; 5132 return;
5129 } 5133 }
5130 ASSERT(ic_data().num_args_tested() == 1); 5134 ASSERT(ic_data().NumArgsTested() == 1);
5131 if (!with_checks()) { 5135 if (!with_checks()) {
5132 ASSERT(ic_data().HasOneTarget()); 5136 ASSERT(ic_data().HasOneTarget());
5133 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); 5137 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0));
5134 compiler->GenerateStaticCall(deopt_id(), 5138 compiler->GenerateStaticCall(deopt_id(),
5135 instance_call()->token_pos(), 5139 instance_call()->token_pos(),
5136 target, 5140 target,
5137 instance_call()->ArgumentCount(), 5141 instance_call()->ArgumentCount(),
5138 instance_call()->argument_names(), 5142 instance_call()->argument_names(),
5139 locs()); 5143 locs());
5140 return; 5144 return;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
5178 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5182 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5179 summary->set_in(0, Location::RequiresRegister()); 5183 summary->set_in(0, Location::RequiresRegister());
5180 if (!IsNullCheck()) { 5184 if (!IsNullCheck()) {
5181 summary->AddTemp(Location::RequiresRegister()); 5185 summary->AddTemp(Location::RequiresRegister());
5182 } 5186 }
5183 return summary; 5187 return summary;
5184 } 5188 }
5185 5189
5186 5190
5187 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5191 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5188 const DeoptReasonId deopt_reason = 5192 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ?
5189 licm_hoisted_ ? kDeoptHoistedCheckClass : kDeoptCheckClass; 5193 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass;
5190 if (IsNullCheck()) { 5194 if (IsNullCheck()) {
5191 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); 5195 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason);
5192 const Immediate& raw_null = 5196 const Immediate& raw_null =
5193 Immediate(reinterpret_cast<intptr_t>(Object::null())); 5197 Immediate(reinterpret_cast<intptr_t>(Object::null()));
5194 __ cmpl(locs()->in(0).reg(), raw_null); 5198 __ cmpl(locs()->in(0).reg(), raw_null);
5195 __ j(EQUAL, deopt); 5199 __ j(EQUAL, deopt);
5196 return; 5200 return;
5197 } 5201 }
5198 5202
5199 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || 5203 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5236 const intptr_t kNumTemps = 0; 5240 const intptr_t kNumTemps = 0;
5237 LocationSummary* summary = 5241 LocationSummary* summary =
5238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5242 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5239 summary->set_in(0, Location::RequiresRegister()); 5243 summary->set_in(0, Location::RequiresRegister());
5240 return summary; 5244 return summary;
5241 } 5245 }
5242 5246
5243 5247
5244 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5248 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5245 Register value = locs()->in(0).reg(); 5249 Register value = locs()->in(0).reg();
5246 Label* deopt = compiler->AddDeoptStub(deopt_id(), 5250 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi);
5247 kDeoptCheckSmi);
5248 __ testl(value, Immediate(kSmiTagMask)); 5251 __ testl(value, Immediate(kSmiTagMask));
5249 __ j(NOT_ZERO, deopt); 5252 __ j(NOT_ZERO, deopt);
5250 } 5253 }
5251 5254
5252 5255
5253 // Length: register or constant. 5256 // Length: register or constant.
5254 // Index: register, constant or stack slot. 5257 // Index: register, constant or stack slot.
5255 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { 5258 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const {
5256 const intptr_t kNumInputs = 2; 5259 const intptr_t kNumInputs = 2;
5257 const intptr_t kNumTemps = 0; 5260 const intptr_t kNumTemps = 0;
5258 LocationSummary* locs = 5261 LocationSummary* locs =
5259 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5262 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5260 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); 5263 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length()));
5261 ConstantInstr* index_constant = index()->definition()->AsConstant(); 5264 ConstantInstr* index_constant = index()->definition()->AsConstant();
5262 if (index_constant != NULL) { 5265 if (index_constant != NULL) {
5263 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); 5266 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index()));
5264 } else { 5267 } else {
5265 locs->set_in(kIndexPos, Location::PrefersRegister()); 5268 locs->set_in(kIndexPos, Location::PrefersRegister());
5266 } 5269 }
5267 return locs; 5270 return locs;
5268 } 5271 }
5269 5272
5270 5273
5271 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5274 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5272 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptCheckArrayBound); 5275 Label* deopt = compiler->AddDeoptStub(deopt_id(),
5276 ICData::kDeoptCheckArrayBound);
5273 5277
5274 Location length_loc = locs()->in(kLengthPos); 5278 Location length_loc = locs()->in(kLengthPos);
5275 Location index_loc = locs()->in(kIndexPos); 5279 Location index_loc = locs()->in(kIndexPos);
5276 5280
5277 if (length_loc.IsConstant() && index_loc.IsConstant()) { 5281 if (length_loc.IsConstant() && index_loc.IsConstant()) {
5278 // TODO(srdjan): remove this code once failures are fixed. 5282 // TODO(srdjan): remove this code once failures are fixed.
5279 if ((Smi::Cast(length_loc.constant()).Value() > 5283 if ((Smi::Cast(length_loc.constant()).Value() >
5280 Smi::Cast(index_loc.constant()).Value()) && 5284 Smi::Cast(index_loc.constant()).Value()) &&
5281 (Smi::Cast(index_loc.constant()).Value() >= 0)) { 5285 (Smi::Cast(index_loc.constant()).Value() >= 0)) {
5282 // This CheckArrayBoundInstr should have been eliminated. 5286 // This CheckArrayBoundInstr should have been eliminated.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
5345 const XmmRegister result = locs()->out(0).fpu_reg(); 5349 const XmmRegister result = locs()->out(0).fpu_reg();
5346 5350
5347 if (value_cid == kMintCid) { 5351 if (value_cid == kMintCid) {
5348 __ movsd(result, FieldAddress(value, Mint::value_offset())); 5352 __ movsd(result, FieldAddress(value, Mint::value_offset()));
5349 } else if (value_cid == kSmiCid) { 5353 } else if (value_cid == kSmiCid) {
5350 __ SmiUntag(value); // Untag input before conversion. 5354 __ SmiUntag(value); // Untag input before conversion.
5351 __ movd(result, value); 5355 __ movd(result, value);
5352 __ pmovsxdq(result, result); 5356 __ pmovsxdq(result, result);
5353 } else { 5357 } else {
5354 Register temp = locs()->temp(0).reg(); 5358 Register temp = locs()->temp(0).reg();
5355 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptUnboxInteger); 5359 Label* deopt = compiler->AddDeoptStub(deopt_id_,
5360 ICData::kDeoptUnboxInteger);
5356 Label is_smi, done; 5361 Label is_smi, done;
5357 __ testl(value, Immediate(kSmiTagMask)); 5362 __ testl(value, Immediate(kSmiTagMask));
5358 __ j(ZERO, &is_smi); 5363 __ j(ZERO, &is_smi);
5359 __ CompareClassId(value, kMintCid, temp); 5364 __ CompareClassId(value, kMintCid, temp);
5360 __ j(NOT_EQUAL, deopt); 5365 __ j(NOT_EQUAL, deopt);
5361 __ movsd(result, FieldAddress(value, Mint::value_offset())); 5366 __ movsd(result, FieldAddress(value, Mint::value_offset()));
5362 __ jmp(&done); 5367 __ jmp(&done);
5363 __ Bind(&is_smi); 5368 __ Bind(&is_smi);
5364 __ movl(temp, value); 5369 __ movl(temp, value);
5365 __ SmiUntag(temp); 5370 __ SmiUntag(temp);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
5497 5502
5498 5503
5499 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5504 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5500 XmmRegister left = locs()->in(0).fpu_reg(); 5505 XmmRegister left = locs()->in(0).fpu_reg();
5501 XmmRegister right = locs()->in(1).fpu_reg(); 5506 XmmRegister right = locs()->in(1).fpu_reg();
5502 5507
5503 ASSERT(locs()->out(0).fpu_reg() == left); 5508 ASSERT(locs()->out(0).fpu_reg() == left);
5504 5509
5505 Label* deopt = NULL; 5510 Label* deopt = NULL;
5506 if (FLAG_throw_on_javascript_int_overflow) { 5511 if (FLAG_throw_on_javascript_int_overflow) {
5507 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp); 5512 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
5508 } 5513 }
5509 switch (op_kind()) { 5514 switch (op_kind()) {
5510 case Token::kBIT_AND: __ andpd(left, right); break; 5515 case Token::kBIT_AND: __ andpd(left, right); break;
5511 case Token::kBIT_OR: __ orpd(left, right); break; 5516 case Token::kBIT_OR: __ orpd(left, right); break;
5512 case Token::kBIT_XOR: __ xorpd(left, right); break; 5517 case Token::kBIT_XOR: __ xorpd(left, right); break;
5513 case Token::kADD: 5518 case Token::kADD:
5514 case Token::kSUB: { 5519 case Token::kSUB: {
5515 Register lo = locs()->temp(0).reg(); 5520 Register lo = locs()->temp(0).reg();
5516 Register hi = locs()->temp(1).reg(); 5521 Register hi = locs()->temp(1).reg();
5517 if (!FLAG_throw_on_javascript_int_overflow) { 5522 if (!FLAG_throw_on_javascript_int_overflow) {
5518 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp); 5523 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
5519 } 5524 }
5520 5525
5521 Label done, overflow; 5526 Label done, overflow;
5522 __ pextrd(lo, right, Immediate(0)); // Lower half 5527 __ pextrd(lo, right, Immediate(0)); // Lower half
5523 __ pextrd(hi, right, Immediate(1)); // Upper half 5528 __ pextrd(hi, right, Immediate(1)); // Upper half
5524 __ subl(ESP, Immediate(2 * kWordSize)); 5529 __ subl(ESP, Immediate(2 * kWordSize));
5525 __ movq(Address(ESP, 0), left); 5530 __ movq(Address(ESP, 0), left);
5526 if (op_kind() == Token::kADD) { 5531 if (op_kind() == Token::kADD) {
5527 __ addl(Address(ESP, 0), lo); 5532 __ addl(Address(ESP, 0), lo);
5528 __ adcl(Address(ESP, 1 * kWordSize), hi); 5533 __ adcl(Address(ESP, 1 * kWordSize), hi);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
5563 summary->set_out(0, Location::SameAsFirstInput()); 5568 summary->set_out(0, Location::SameAsFirstInput());
5564 return summary; 5569 return summary;
5565 } 5570 }
5566 5571
5567 5572
5568 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5573 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5569 XmmRegister left = locs()->in(0).fpu_reg(); 5574 XmmRegister left = locs()->in(0).fpu_reg();
5570 ASSERT(locs()->in(1).reg() == ECX); 5575 ASSERT(locs()->in(1).reg() == ECX);
5571 ASSERT(locs()->out(0).fpu_reg() == left); 5576 ASSERT(locs()->out(0).fpu_reg() == left);
5572 5577
5573 Label* deopt = compiler->AddDeoptStub(deopt_id(), 5578 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
5574 kDeoptShiftMintOp);
5575 Label done; 5579 Label done;
5576 __ testl(ECX, ECX); 5580 __ testl(ECX, ECX);
5577 __ j(ZERO, &done); // Shift by 0 is a nop. 5581 __ j(ZERO, &done); // Shift by 0 is a nop.
5578 __ subl(ESP, Immediate(2 * kWordSize)); 5582 __ subl(ESP, Immediate(2 * kWordSize));
5579 __ movq(Address(ESP, 0), left); 5583 __ movq(Address(ESP, 0), left);
5580 // Deoptimize if shift count is > 31. 5584 // Deoptimize if shift count is > 31.
5581 // sarl operation masks the count to 5 bits and 5585 // sarl operation masks the count to 5 bits and
5582 // shrd is undefined with count > operand size (32) 5586 // shrd is undefined with count > operand size (32)
5583 // TODO(fschneider): Support shift counts > 31 without deoptimization. 5587 // TODO(fschneider): Support shift counts > 31 without deoptimization.
5584 __ SmiUntag(ECX); 5588 __ SmiUntag(ECX);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
5637 return summary; 5641 return summary;
5638 } 5642 }
5639 5643
5640 5644
5641 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5645 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5642 ASSERT(op_kind() == Token::kBIT_NOT); 5646 ASSERT(op_kind() == Token::kBIT_NOT);
5643 XmmRegister value = locs()->in(0).fpu_reg(); 5647 XmmRegister value = locs()->in(0).fpu_reg();
5644 ASSERT(value == locs()->out(0).fpu_reg()); 5648 ASSERT(value == locs()->out(0).fpu_reg());
5645 Label* deopt = NULL; 5649 Label* deopt = NULL;
5646 if (FLAG_throw_on_javascript_int_overflow) { 5650 if (FLAG_throw_on_javascript_int_overflow) {
5647 deopt = compiler->AddDeoptStub(deopt_id(), 5651 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp);
5648 kDeoptUnaryMintOp);
5649 } 5652 }
5650 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. 5653 __ pcmpeqq(XMM0, XMM0); // Generate all 1's.
5651 __ pxor(value, XMM0); 5654 __ pxor(value, XMM0);
5652 if (FLAG_throw_on_javascript_int_overflow) { 5655 if (FLAG_throw_on_javascript_int_overflow) {
5653 Register tmp = locs()->temp(0).reg(); 5656 Register tmp = locs()->temp(0).reg();
5654 EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp); 5657 EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp);
5655 } 5658 }
5656 } 5659 }
5657 5660
5658 5661
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
5981 PcDescriptors::kOther, 5984 PcDescriptors::kOther,
5982 locs()); 5985 locs());
5983 __ Drop(ArgumentCount()); // Discard arguments. 5986 __ Drop(ArgumentCount()); // Discard arguments.
5984 } 5987 }
5985 5988
5986 } // namespace dart 5989 } // namespace dart
5987 5990
5988 #undef __ 5991 #undef __
5989 5992
5990 #endif // defined TARGET_ARCH_IA32 5993 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698