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

Side by Side Diff: src/mips/lithium-codegen-mips.cc

Issue 141363005: A64: Synchronize with r15204. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 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 | « src/mips/lithium-codegen-mips.h ('k') | src/mips/lithium-mips.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 } 554 }
555 555
556 556
557 MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const { 557 MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const {
558 ASSERT(op->IsDoubleStackSlot()); 558 ASSERT(op->IsDoubleStackSlot());
559 return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize); 559 return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize);
560 } 560 }
561 561
562 562
563 void LCodeGen::WriteTranslation(LEnvironment* environment, 563 void LCodeGen::WriteTranslation(LEnvironment* environment,
564 Translation* translation, 564 Translation* translation) {
565 int* pushed_arguments_index,
566 int* pushed_arguments_count) {
567 if (environment == NULL) return; 565 if (environment == NULL) return;
568 566
569 // The translation includes one command per value in the environment. 567 // The translation includes one command per value in the environment.
570 int translation_size = environment->values()->length(); 568 int translation_size = environment->translation_size();
571 // The output frame height does not include the parameters. 569 // The output frame height does not include the parameters.
572 int height = translation_size - environment->parameter_count(); 570 int height = translation_size - environment->parameter_count();
573 571
574 // Function parameters are arguments to the outermost environment. The 572 WriteTranslation(environment->outer(), translation);
575 // arguments index points to the first element of a sequence of tagged
576 // values on the stack that represent the arguments. This needs to be
577 // kept in sync with the LArgumentsElements implementation.
578 *pushed_arguments_index = -environment->parameter_count();
579 *pushed_arguments_count = environment->parameter_count();
580
581 WriteTranslation(environment->outer(),
582 translation,
583 pushed_arguments_index,
584 pushed_arguments_count);
585 bool has_closure_id = !info()->closure().is_null() && 573 bool has_closure_id = !info()->closure().is_null() &&
586 !info()->closure().is_identical_to(environment->closure()); 574 !info()->closure().is_identical_to(environment->closure());
587 int closure_id = has_closure_id 575 int closure_id = has_closure_id
588 ? DefineDeoptimizationLiteral(environment->closure()) 576 ? DefineDeoptimizationLiteral(environment->closure())
589 : Translation::kSelfLiteralId; 577 : Translation::kSelfLiteralId;
590 578
591 switch (environment->frame_type()) { 579 switch (environment->frame_type()) {
592 case JS_FUNCTION: 580 case JS_FUNCTION:
593 translation->BeginJSFrame(environment->ast_id(), closure_id, height); 581 translation->BeginJSFrame(environment->ast_id(), closure_id, height);
594 break; 582 break;
(...skipping 11 matching lines...) Expand all
606 translation->BeginSetterStubFrame(closure_id); 594 translation->BeginSetterStubFrame(closure_id);
607 break; 595 break;
608 case STUB: 596 case STUB:
609 translation->BeginCompiledStubFrame(); 597 translation->BeginCompiledStubFrame();
610 break; 598 break;
611 case ARGUMENTS_ADAPTOR: 599 case ARGUMENTS_ADAPTOR:
612 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 600 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
613 break; 601 break;
614 } 602 }
615 603
616 // Inlined frames which push their arguments cause the index to be
617 // bumped and another stack area to be used for materialization,
618 // otherwise actual argument values are unknown for inlined frames.
619 bool arguments_known = true;
620 int arguments_index = *pushed_arguments_index;
621 int arguments_count = *pushed_arguments_count;
622 if (environment->entry() != NULL) {
623 arguments_known = environment->entry()->arguments_pushed();
624 arguments_index = arguments_index < 0
625 ? GetStackSlotCount() : arguments_index + arguments_count;
626 arguments_count = environment->entry()->arguments_count() + 1;
627 if (environment->entry()->arguments_pushed()) {
628 *pushed_arguments_index = arguments_index;
629 *pushed_arguments_count = arguments_count;
630 }
631 }
632
633 for (int i = 0; i < translation_size; ++i) { 604 for (int i = 0; i < translation_size; ++i) {
634 LOperand* value = environment->values()->at(i); 605 LOperand* value = environment->values()->at(i);
635 // spilled_registers_ and spilled_double_registers_ are either 606 // spilled_registers_ and spilled_double_registers_ are either
636 // both NULL or both set. 607 // both NULL or both set.
637 if (environment->spilled_registers() != NULL && value != NULL) { 608 if (environment->spilled_registers() != NULL && value != NULL) {
638 if (value->IsRegister() && 609 if (value->IsRegister() &&
639 environment->spilled_registers()[value->index()] != NULL) { 610 environment->spilled_registers()[value->index()] != NULL) {
640 translation->MarkDuplicate(); 611 translation->MarkDuplicate();
641 AddToTranslation(translation, 612 AddToTranslation(translation,
642 environment->spilled_registers()[value->index()], 613 environment->spilled_registers()[value->index()],
643 environment->HasTaggedValueAt(i), 614 environment->HasTaggedValueAt(i),
644 environment->HasUint32ValueAt(i), 615 environment->HasUint32ValueAt(i));
645 arguments_known,
646 arguments_index,
647 arguments_count);
648 } else if ( 616 } else if (
649 value->IsDoubleRegister() && 617 value->IsDoubleRegister() &&
650 environment->spilled_double_registers()[value->index()] != NULL) { 618 environment->spilled_double_registers()[value->index()] != NULL) {
651 translation->MarkDuplicate(); 619 translation->MarkDuplicate();
652 AddToTranslation( 620 AddToTranslation(
653 translation, 621 translation,
654 environment->spilled_double_registers()[value->index()], 622 environment->spilled_double_registers()[value->index()],
655 false, 623 false,
656 false, 624 false);
657 arguments_known,
658 arguments_index,
659 arguments_count);
660 } 625 }
661 } 626 }
662 627
628 // TODO(mstarzinger): Introduce marker operands to indicate that this value
629 // is not present and must be reconstructed from the deoptimizer. Currently
630 // this is only used for the arguments object.
631 if (value == NULL) {
632 int arguments_count = environment->values()->length() - translation_size;
633 translation->BeginArgumentsObject(arguments_count);
634 for (int i = 0; i < arguments_count; ++i) {
635 LOperand* value = environment->values()->at(translation_size + i);
636 ASSERT(environment->spilled_registers() == NULL ||
637 !value->IsRegister() ||
638 environment->spilled_registers()[value->index()] == NULL);
639 ASSERT(environment->spilled_registers() == NULL ||
640 !value->IsDoubleRegister() ||
641 environment->spilled_double_registers()[value->index()] == NULL);
642 AddToTranslation(translation,
643 value,
644 environment->HasTaggedValueAt(translation_size + i),
645 environment->HasUint32ValueAt(translation_size + i));
646 }
647 continue;
648 }
649
663 AddToTranslation(translation, 650 AddToTranslation(translation,
664 value, 651 value,
665 environment->HasTaggedValueAt(i), 652 environment->HasTaggedValueAt(i),
666 environment->HasUint32ValueAt(i), 653 environment->HasUint32ValueAt(i));
667 arguments_known,
668 arguments_index,
669 arguments_count);
670 } 654 }
671 } 655 }
672 656
673 657
674 void LCodeGen::AddToTranslation(Translation* translation, 658 void LCodeGen::AddToTranslation(Translation* translation,
675 LOperand* op, 659 LOperand* op,
676 bool is_tagged, 660 bool is_tagged,
677 bool is_uint32, 661 bool is_uint32) {
678 bool arguments_known, 662 if (op->IsStackSlot()) {
679 int arguments_index,
680 int arguments_count) {
681 if (op == NULL) {
682 // TODO(twuerthinger): Introduce marker operands to indicate that this value
683 // is not present and must be reconstructed from the deoptimizer. Currently
684 // this is only used for the arguments object.
685 translation->StoreArgumentsObject(
686 arguments_known, arguments_index, arguments_count);
687 } else if (op->IsStackSlot()) {
688 if (is_tagged) { 663 if (is_tagged) {
689 translation->StoreStackSlot(op->index()); 664 translation->StoreStackSlot(op->index());
690 } else if (is_uint32) { 665 } else if (is_uint32) {
691 translation->StoreUint32StackSlot(op->index()); 666 translation->StoreUint32StackSlot(op->index());
692 } else { 667 } else {
693 translation->StoreInt32StackSlot(op->index()); 668 translation->StoreInt32StackSlot(op->index());
694 } 669 }
695 } else if (op->IsDoubleStackSlot()) { 670 } else if (op->IsDoubleStackSlot()) {
696 translation->StoreDoubleStackSlot(op->index()); 671 translation->StoreDoubleStackSlot(op->index());
697 } else if (op->IsArgument()) { 672 } else if (op->IsArgument()) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 // 0 ..................................................... size-1 747 // 0 ..................................................... size-1
773 // [parameters] [locals] [expression stack including arguments] 748 // [parameters] [locals] [expression stack including arguments]
774 749
775 // Layout of the translation: 750 // Layout of the translation:
776 // 0 ........................................................ size - 1 + 4 751 // 0 ........................................................ size - 1 + 4
777 // [expression stack including arguments] [locals] [4 words] [parameters] 752 // [expression stack including arguments] [locals] [4 words] [parameters]
778 // |>------------ translation_size ------------<| 753 // |>------------ translation_size ------------<|
779 754
780 int frame_count = 0; 755 int frame_count = 0;
781 int jsframe_count = 0; 756 int jsframe_count = 0;
782 int args_index = 0;
783 int args_count = 0;
784 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 757 for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
785 ++frame_count; 758 ++frame_count;
786 if (e->frame_type() == JS_FUNCTION) { 759 if (e->frame_type() == JS_FUNCTION) {
787 ++jsframe_count; 760 ++jsframe_count;
788 } 761 }
789 } 762 }
790 Translation translation(&translations_, frame_count, jsframe_count, zone()); 763 Translation translation(&translations_, frame_count, jsframe_count, zone());
791 WriteTranslation(environment, &translation, &args_index, &args_count); 764 WriteTranslation(environment, &translation);
792 int deoptimization_index = deoptimizations_.length(); 765 int deoptimization_index = deoptimizations_.length();
793 int pc_offset = masm()->pc_offset(); 766 int pc_offset = masm()->pc_offset();
794 environment->Register(deoptimization_index, 767 environment->Register(deoptimization_index,
795 translation.index(), 768 translation.index(),
796 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 769 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
797 deoptimizations_.Add(environment, zone()); 770 deoptimizations_.Add(environment, zone());
798 } 771 }
799 } 772 }
800 773
801 774
(...skipping 14 matching lines...) Expand all
816 } 789 }
817 790
818 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on MIPS. 791 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on MIPS.
819 if (FLAG_deopt_every_n_times == 1 && 792 if (FLAG_deopt_every_n_times == 1 &&
820 !info()->IsStub() && 793 !info()->IsStub() &&
821 info()->opt_count() == id) { 794 info()->opt_count() == id) {
822 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); 795 __ Jump(entry, RelocInfo::RUNTIME_ENTRY);
823 return; 796 return;
824 } 797 }
825 798
826 if (FLAG_trap_on_deopt) { 799 if (FLAG_trap_on_deopt && info()->IsOptimizing()) {
827 Label skip; 800 Label skip;
828 if (cc != al) { 801 if (cc != al) {
829 __ Branch(&skip, NegateCondition(cc), src1, src2); 802 __ Branch(&skip, NegateCondition(cc), src1, src2);
830 } 803 }
831 __ stop("trap_on_deopt"); 804 __ stop("trap_on_deopt");
832 __ bind(&skip); 805 __ bind(&skip);
833 } 806 }
834 807
835 ASSERT(info()->IsStub() || frame_is_built_); 808 ASSERT(info()->IsStub() || frame_is_built_);
836 bool needs_lazy_deopt = info()->IsStub(); 809 bool needs_lazy_deopt = info()->IsStub();
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 __ mfhi(result_reg); 1169 __ mfhi(result_reg);
1197 1170
1198 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1171 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1199 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); 1172 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
1200 } 1173 }
1201 __ bind(&done); 1174 __ bind(&done);
1202 } 1175 }
1203 } 1176 }
1204 1177
1205 1178
1179 void LCodeGen::EmitSignedIntegerDivisionByConstant(
1180 Register result,
1181 Register dividend,
1182 int32_t divisor,
1183 Register remainder,
1184 Register scratch,
1185 LEnvironment* environment) {
1186 ASSERT(!AreAliased(dividend, scratch, at, no_reg));
1187 ASSERT(LChunkBuilder::HasMagicNumberForDivisor(divisor));
1188
1189 uint32_t divisor_abs = abs(divisor);
1190
1191 int32_t power_of_2_factor =
1192 CompilerIntrinsics::CountTrailingZeros(divisor_abs);
1193
1194 switch (divisor_abs) {
1195 case 0:
1196 DeoptimizeIf(al, environment);
1197 return;
1198
1199 case 1:
1200 if (divisor > 0) {
1201 __ Move(result, dividend);
1202 } else {
1203 __ SubuAndCheckForOverflow(result, zero_reg, dividend, scratch);
1204 DeoptimizeIf(lt, environment, scratch, Operand(zero_reg));
1205 }
1206 // Compute the remainder.
1207 __ Move(remainder, zero_reg);
1208 return;
1209
1210 default:
1211 if (IsPowerOf2(divisor_abs)) {
1212 // Branch and condition free code for integer division by a power
1213 // of two.
1214 int32_t power = WhichPowerOf2(divisor_abs);
1215 if (power > 1) {
1216 __ sra(scratch, dividend, power - 1);
1217 }
1218 __ srl(scratch, scratch, 32 - power);
1219 __ Addu(scratch, dividend, Operand(scratch));
1220 __ sra(result, scratch, power);
1221 // Negate if necessary.
1222 // We don't need to check for overflow because the case '-1' is
1223 // handled separately.
1224 if (divisor < 0) {
1225 ASSERT(divisor != -1);
1226 __ Subu(result, zero_reg, Operand(result));
1227 }
1228 // Compute the remainder.
1229 if (divisor > 0) {
1230 __ sll(scratch, result, power);
1231 __ Subu(remainder, dividend, Operand(scratch));
1232 } else {
1233 __ sll(scratch, result, power);
1234 __ Addu(remainder, dividend, Operand(scratch));
1235 }
1236 return;
1237 } else if (LChunkBuilder::HasMagicNumberForDivisor(divisor)) {
1238 // Use magic numbers for a few specific divisors.
1239 // Details and proofs can be found in:
1240 // - Hacker's Delight, Henry S. Warren, Jr.
1241 // - The PowerPC Compiler Writer's Guide
1242 // and probably many others.
1243 //
1244 // We handle
1245 // <divisor with magic numbers> * <power of 2>
1246 // but not
1247 // <divisor with magic numbers> * <other divisor with magic numbers>
1248 DivMagicNumbers magic_numbers =
1249 DivMagicNumberFor(divisor_abs >> power_of_2_factor);
1250 // Branch and condition free code for integer division by a power
1251 // of two.
1252 const int32_t M = magic_numbers.M;
1253 const int32_t s = magic_numbers.s + power_of_2_factor;
1254
1255 __ li(scratch, Operand(M));
1256 __ mult(dividend, scratch);
1257 __ mfhi(scratch);
1258 if (M < 0) {
1259 __ Addu(scratch, scratch, Operand(dividend));
1260 }
1261 if (s > 0) {
1262 __ sra(scratch, scratch, s);
1263 __ mov(scratch, scratch);
1264 }
1265 __ srl(at, dividend, 31);
1266 __ Addu(result, scratch, Operand(at));
1267 if (divisor < 0) __ Subu(result, zero_reg, Operand(result));
1268 // Compute the remainder.
1269 __ li(scratch, Operand(divisor));
1270 __ Mul(scratch, result, Operand(scratch));
1271 __ Subu(remainder, dividend, Operand(scratch));
1272 } else {
1273 __ li(scratch, Operand(divisor));
1274 __ div(dividend, scratch);
1275 __ mfhi(remainder);
1276 __ mflo(result);
1277 }
1278 }
1279 }
1280
1281
1206 void LCodeGen::DoDivI(LDivI* instr) { 1282 void LCodeGen::DoDivI(LDivI* instr) {
1207 const Register left = ToRegister(instr->left()); 1283 const Register left = ToRegister(instr->left());
1208 const Register right = ToRegister(instr->right()); 1284 const Register right = ToRegister(instr->right());
1209 const Register result = ToRegister(instr->result()); 1285 const Register result = ToRegister(instr->result());
1210 1286
1211 // On MIPS div is asynchronous - it will run in the background while we 1287 // On MIPS div is asynchronous - it will run in the background while we
1212 // check for special cases. 1288 // check for special cases.
1213 __ div(left, right); 1289 __ div(left, right);
1214 1290
1215 // Check for x / 0. 1291 // Check for x / 0.
(...skipping 30 matching lines...) Expand all
1246 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); 1322 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
1247 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand()); 1323 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
1248 1324
1249 // This is computed in-place. 1325 // This is computed in-place.
1250 ASSERT(addend.is(ToDoubleRegister(instr->result()))); 1326 ASSERT(addend.is(ToDoubleRegister(instr->result())));
1251 1327
1252 __ madd_d(addend, addend, multiplier, multiplicand); 1328 __ madd_d(addend, addend, multiplier, multiplicand);
1253 } 1329 }
1254 1330
1255 1331
1332 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1333 const Register result = ToRegister(instr->result());
1334 const Register left = ToRegister(instr->left());
1335 const Register remainder = ToRegister(instr->temp());
1336 const Register scratch = scratch0();
1337
1338 if (instr->right()->IsConstantOperand()) {
1339 Label done;
1340 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
1341 if (divisor < 0) {
1342 DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg));
1343 }
1344 EmitSignedIntegerDivisionByConstant(result,
1345 left,
1346 divisor,
1347 remainder,
1348 scratch,
1349 instr->environment());
1350 // We performed a truncating division. Correct the result if necessary.
1351 __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT);
1352 __ Xor(scratch , remainder, Operand(divisor));
1353 __ Branch(&done, ge, scratch, Operand(zero_reg));
1354 __ Subu(result, result, Operand(1));
1355 __ bind(&done);
1356 } else {
1357 Label done;
1358 const Register right = ToRegister(instr->right());
1359
1360 // On MIPS div is asynchronous - it will run in the background while we
1361 // check for special cases.
1362 __ div(left, right);
1363
1364 // Check for x / 0.
1365 DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
1366
1367 // Check for (0 / -x) that will produce negative zero.
1368 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1369 Label left_not_zero;
1370 __ Branch(&left_not_zero, ne, left, Operand(zero_reg));
1371 DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg));
1372 __ bind(&left_not_zero);
1373 }
1374
1375 // Check for (kMinInt / -1).
1376 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1377 Label left_not_min_int;
1378 __ Branch(&left_not_min_int, ne, left, Operand(kMinInt));
1379 DeoptimizeIf(eq, instr->environment(), right, Operand(-1));
1380 __ bind(&left_not_min_int);
1381 }
1382
1383 __ mfhi(remainder);
1384 __ mflo(result);
1385
1386 // We performed a truncating division. Correct the result if necessary.
1387 __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT);
1388 __ Xor(scratch , remainder, Operand(right));
1389 __ Branch(&done, ge, scratch, Operand(zero_reg));
1390 __ Subu(result, result, Operand(1));
1391 __ bind(&done);
1392 }
1393 }
1394
1395
1256 void LCodeGen::DoMulI(LMulI* instr) { 1396 void LCodeGen::DoMulI(LMulI* instr) {
1257 Register scratch = scratch0(); 1397 Register scratch = scratch0();
1258 Register result = ToRegister(instr->result()); 1398 Register result = ToRegister(instr->result());
1259 // Note that result may alias left. 1399 // Note that result may alias left.
1260 Register left = ToRegister(instr->left()); 1400 Register left = ToRegister(instr->left());
1261 LOperand* right_op = instr->right(); 1401 LOperand* right_op = instr->right();
1262 1402
1263 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1403 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1264 bool bailout_on_minus_zero = 1404 bool bailout_on_minus_zero =
1265 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1405 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after
2459 // instanceof stub. 2599 // instanceof stub.
2460 Label cache_miss; 2600 Label cache_miss;
2461 Register map = temp; 2601 Register map = temp;
2462 __ lw(map, FieldMemOperand(object, HeapObject::kMapOffset)); 2602 __ lw(map, FieldMemOperand(object, HeapObject::kMapOffset));
2463 2603
2464 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 2604 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
2465 __ bind(deferred->map_check()); // Label for calculating code patching. 2605 __ bind(deferred->map_check()); // Label for calculating code patching.
2466 // We use Factory::the_hole_value() on purpose instead of loading from the 2606 // We use Factory::the_hole_value() on purpose instead of loading from the
2467 // root array to force relocation to be able to later patch with 2607 // root array to force relocation to be able to later patch with
2468 // the cached map. 2608 // the cached map.
2469 Handle<JSGlobalPropertyCell> cell = 2609 Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value());
2470 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
2471 __ li(at, Operand(Handle<Object>(cell))); 2610 __ li(at, Operand(Handle<Object>(cell)));
2472 __ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset)); 2611 __ lw(at, FieldMemOperand(at, PropertyCell::kValueOffset));
2473 __ Branch(&cache_miss, ne, map, Operand(at)); 2612 __ Branch(&cache_miss, ne, map, Operand(at));
2474 // We use Factory::the_hole_value() on purpose instead of loading from the 2613 // We use Factory::the_hole_value() on purpose instead of loading from the
2475 // root array to force relocation to be able to later patch 2614 // root array to force relocation to be able to later patch
2476 // with true or false. 2615 // with true or false.
2477 __ li(result, Operand(factory()->the_hole_value()), CONSTANT_SIZE); 2616 __ li(result, Operand(factory()->the_hole_value()), CONSTANT_SIZE);
2478 __ Branch(&done); 2617 __ Branch(&done);
2479 2618
2480 // The inlined call site cache did not match. Check null and string before 2619 // The inlined call site cache did not match. Check null and string before
2481 // calling the deferred code. 2620 // calling the deferred code.
2482 __ bind(&cache_miss); 2621 __ bind(&cache_miss);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2616 2755
2617 if (no_frame_start != -1) { 2756 if (no_frame_start != -1) {
2618 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); 2757 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset());
2619 } 2758 }
2620 } 2759 }
2621 2760
2622 2761
2623 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 2762 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2624 Register result = ToRegister(instr->result()); 2763 Register result = ToRegister(instr->result());
2625 __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell()))); 2764 __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell())));
2626 __ lw(result, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset)); 2765 __ lw(result, FieldMemOperand(at, Cell::kValueOffset));
2627 if (instr->hydrogen()->RequiresHoleCheck()) { 2766 if (instr->hydrogen()->RequiresHoleCheck()) {
2628 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2767 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2629 DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 2768 DeoptimizeIf(eq, instr->environment(), result, Operand(at));
2630 } 2769 }
2631 } 2770 }
2632 2771
2633 2772
2634 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 2773 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2635 ASSERT(ToRegister(instr->global_object()).is(a0)); 2774 ASSERT(ToRegister(instr->global_object()).is(a0));
2636 ASSERT(ToRegister(instr->result()).is(v0)); 2775 ASSERT(ToRegister(instr->result()).is(v0));
(...skipping 13 matching lines...) Expand all
2650 // Load the cell. 2789 // Load the cell.
2651 __ li(cell, Operand(instr->hydrogen()->cell())); 2790 __ li(cell, Operand(instr->hydrogen()->cell()));
2652 2791
2653 // If the cell we are storing to contains the hole it could have 2792 // If the cell we are storing to contains the hole it could have
2654 // been deleted from the property dictionary. In that case, we need 2793 // been deleted from the property dictionary. In that case, we need
2655 // to update the property details in the property dictionary to mark 2794 // to update the property details in the property dictionary to mark
2656 // it as no longer deleted. 2795 // it as no longer deleted.
2657 if (instr->hydrogen()->RequiresHoleCheck()) { 2796 if (instr->hydrogen()->RequiresHoleCheck()) {
2658 // We use a temp to check the payload. 2797 // We use a temp to check the payload.
2659 Register payload = ToRegister(instr->temp()); 2798 Register payload = ToRegister(instr->temp());
2660 __ lw(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 2799 __ lw(payload, FieldMemOperand(cell, Cell::kValueOffset));
2661 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2800 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2662 DeoptimizeIf(eq, instr->environment(), payload, Operand(at)); 2801 DeoptimizeIf(eq, instr->environment(), payload, Operand(at));
2663 } 2802 }
2664 2803
2665 // Store the value. 2804 // Store the value.
2666 __ sw(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 2805 __ sw(value, FieldMemOperand(cell, Cell::kValueOffset));
2667 // Cells are always rescanned, so no write barrier here. 2806 // Cells are always rescanned, so no write barrier here.
2668 } 2807 }
2669 2808
2670 2809
2671 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { 2810 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
2672 ASSERT(ToRegister(instr->global_object()).is(a1)); 2811 ASSERT(ToRegister(instr->global_object()).is(a1));
2673 ASSERT(ToRegister(instr->value()).is(a0)); 2812 ASSERT(ToRegister(instr->value()).is(a0));
2674 2813
2675 __ li(a2, Operand(instr->name())); 2814 __ li(a2, Operand(instr->name()));
2676 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 2815 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
(...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after
3924 __ li(a0, Operand(instr->arity())); 4063 __ li(a0, Operand(instr->arity()));
3925 __ li(a2, Operand(instr->hydrogen()->property_cell())); 4064 __ li(a2, Operand(instr->hydrogen()->property_cell()));
3926 ElementsKind kind = instr->hydrogen()->elements_kind(); 4065 ElementsKind kind = instr->hydrogen()->elements_kind();
3927 bool disable_allocation_sites = 4066 bool disable_allocation_sites =
3928 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE); 4067 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE);
3929 4068
3930 if (instr->arity() == 0) { 4069 if (instr->arity() == 0) {
3931 ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites); 4070 ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites);
3932 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4071 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3933 } else if (instr->arity() == 1) { 4072 } else if (instr->arity() == 1) {
4073 Label done;
4074 if (IsFastPackedElementsKind(kind)) {
4075 Label packed_case;
4076 // We might need a change here,
4077 // look at the first argument.
4078 __ lw(t1, MemOperand(sp, 0));
4079 __ Branch(&packed_case, eq, t1, Operand(zero_reg));
4080
4081 ElementsKind holey_kind = GetHoleyElementsKind(kind);
4082 ArraySingleArgumentConstructorStub stub(holey_kind,
4083 disable_allocation_sites);
4084 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4085 __ jmp(&done);
4086 __ bind(&packed_case);
4087 }
4088
3934 ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites); 4089 ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites);
3935 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4090 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4091 __ bind(&done);
3936 } else { 4092 } else {
3937 ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites); 4093 ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites);
3938 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4094 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3939 } 4095 }
3940 } 4096 }
3941 4097
3942 4098
3943 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 4099 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3944 CallRuntime(instr->function(), instr->arity(), instr); 4100 CallRuntime(instr->function(), instr->arity(), instr);
3945 } 4101 }
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after
5021 } 5177 }
5022 } 5178 }
5023 5179
5024 5180
5025 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { 5181 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
5026 Register reg = ToRegister(instr->value()); 5182 Register reg = ToRegister(instr->value());
5027 Handle<JSFunction> target = instr->hydrogen()->target(); 5183 Handle<JSFunction> target = instr->hydrogen()->target();
5028 AllowDeferredHandleDereference smi_check; 5184 AllowDeferredHandleDereference smi_check;
5029 if (isolate()->heap()->InNewSpace(*target)) { 5185 if (isolate()->heap()->InNewSpace(*target)) {
5030 Register reg = ToRegister(instr->value()); 5186 Register reg = ToRegister(instr->value());
5031 Handle<JSGlobalPropertyCell> cell = 5187 Handle<Cell> cell = isolate()->factory()->NewPropertyCell(target);
5032 isolate()->factory()->NewJSGlobalPropertyCell(target);
5033 __ li(at, Operand(Handle<Object>(cell))); 5188 __ li(at, Operand(Handle<Object>(cell)));
5034 __ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset)); 5189 __ lw(at, FieldMemOperand(at, Cell::kValueOffset));
5035 DeoptimizeIf(ne, instr->environment(), reg, 5190 DeoptimizeIf(ne, instr->environment(), reg,
5036 Operand(at)); 5191 Operand(at));
5037 } else { 5192 } else {
5038 DeoptimizeIf(ne, instr->environment(), reg, 5193 DeoptimizeIf(ne, instr->environment(), reg,
5039 Operand(target)); 5194 Operand(target));
5040 } 5195 }
5041 } 5196 }
5042 5197
5043 5198
5044 void LCodeGen::DoCheckMapCommon(Register map_reg, 5199 void LCodeGen::DoCheckMapCommon(Register map_reg,
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
5693 __ Subu(scratch, result, scratch); 5848 __ Subu(scratch, result, scratch);
5694 __ lw(result, FieldMemOperand(scratch, 5849 __ lw(result, FieldMemOperand(scratch,
5695 FixedArray::kHeaderSize - kPointerSize)); 5850 FixedArray::kHeaderSize - kPointerSize));
5696 __ bind(&done); 5851 __ bind(&done);
5697 } 5852 }
5698 5853
5699 5854
5700 #undef __ 5855 #undef __
5701 5856
5702 } } // namespace v8::internal 5857 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips/lithium-codegen-mips.h ('k') | src/mips/lithium-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698