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

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

Issue 6793017: In LCodeGen::DoDeferredLInstanceOfKnownGlobal emit safepoint with registers for the call to stub. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: port to arm and x64 Created 9 years, 8 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 translation->StoreLiteral(src_index); 477 translation->StoreLiteral(src_index);
478 } else { 478 } else {
479 UNREACHABLE(); 479 UNREACHABLE();
480 } 480 }
481 } 481 }
482 482
483 483
484 void LCodeGen::CallCode(Handle<Code> code, 484 void LCodeGen::CallCode(Handle<Code> code,
485 RelocInfo::Mode mode, 485 RelocInfo::Mode mode,
486 LInstruction* instr) { 486 LInstruction* instr) {
487 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
488 }
489
490
491 void LCodeGen::CallCodeGeneric(Handle<Code> code,
492 RelocInfo::Mode mode,
493 LInstruction* instr,
494 SafepointMode safepoint_mode) {
487 ASSERT(instr != NULL); 495 ASSERT(instr != NULL);
488 LPointerMap* pointers = instr->pointer_map(); 496 LPointerMap* pointers = instr->pointer_map();
489 RecordPosition(pointers->position()); 497 RecordPosition(pointers->position());
490 __ Call(code, mode); 498 __ Call(code, mode);
491 RegisterLazyDeoptimization(instr); 499 RegisterLazyDeoptimization(instr, safepoint_mode);
492 } 500 }
493 501
494 502
495 void LCodeGen::CallRuntime(const Runtime::Function* function, 503 void LCodeGen::CallRuntime(const Runtime::Function* function,
496 int num_arguments, 504 int num_arguments,
497 LInstruction* instr) { 505 LInstruction* instr) {
498 ASSERT(instr != NULL); 506 ASSERT(instr != NULL);
499 LPointerMap* pointers = instr->pointer_map(); 507 LPointerMap* pointers = instr->pointer_map();
500 ASSERT(pointers != NULL); 508 ASSERT(pointers != NULL);
501 RecordPosition(pointers->position()); 509 RecordPosition(pointers->position());
502 510
503 __ CallRuntime(function, num_arguments); 511 __ CallRuntime(function, num_arguments);
504 RegisterLazyDeoptimization(instr); 512 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT);
505 } 513 }
506 514
507 515
508 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr) { 516 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
517 int argc,
518 LInstruction* instr) {
519 __ CallRuntimeSaveDoubles(id);
520 RecordSafepointWithRegisters(
521 instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex);
522 }
523
524
525 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr,
526 SafepointMode safepoint_mode) {
509 // Create the environment to bailout to. If the call has side effects 527 // Create the environment to bailout to. If the call has side effects
510 // execution has to continue after the call otherwise execution can continue 528 // execution has to continue after the call otherwise execution can continue
511 // from a previous bailout point repeating the call. 529 // from a previous bailout point repeating the call.
512 LEnvironment* deoptimization_environment; 530 LEnvironment* deoptimization_environment;
513 if (instr->HasDeoptimizationEnvironment()) { 531 if (instr->HasDeoptimizationEnvironment()) {
514 deoptimization_environment = instr->deoptimization_environment(); 532 deoptimization_environment = instr->deoptimization_environment();
515 } else { 533 } else {
516 deoptimization_environment = instr->environment(); 534 deoptimization_environment = instr->environment();
517 } 535 }
518 536
519 RegisterEnvironmentForDeoptimization(deoptimization_environment); 537 RegisterEnvironmentForDeoptimization(deoptimization_environment);
520 RecordSafepoint(instr->pointer_map(), 538 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
521 deoptimization_environment->deoptimization_index()); 539 RecordSafepoint(instr->pointer_map(),
540 deoptimization_environment->deoptimization_index());
541 } else {
542 ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
543 RecordSafepointWithRegisters(
544 instr->pointer_map(),
545 0,
546 deoptimization_environment->deoptimization_index());
547 }
522 } 548 }
523 549
524 550
525 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) { 551 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) {
526 if (!environment->HasBeenRegistered()) { 552 if (!environment->HasBeenRegistered()) {
527 // Physical stack frame layout: 553 // Physical stack frame layout:
528 // -x ............. -4 0 ..................................... y 554 // -x ............. -4 0 ..................................... y
529 // [incoming arguments] [spill slots] [pushed outgoing arguments] 555 // [incoming arguments] [spill slots] [pushed outgoing arguments]
530 556
531 // Layout of the environment: 557 // Layout of the environment:
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 669
644 inlined_function_count_ = deoptimization_literals_.length(); 670 inlined_function_count_ = deoptimization_literals_.length();
645 } 671 }
646 672
647 673
648 void LCodeGen::RecordSafepoint( 674 void LCodeGen::RecordSafepoint(
649 LPointerMap* pointers, 675 LPointerMap* pointers,
650 Safepoint::Kind kind, 676 Safepoint::Kind kind,
651 int arguments, 677 int arguments,
652 int deoptimization_index) { 678 int deoptimization_index) {
679 ASSERT(expected_safepoint_kind_ == kind);
680
653 const ZoneList<LOperand*>* operands = pointers->operands(); 681 const ZoneList<LOperand*>* operands = pointers->operands();
654 Safepoint safepoint = safepoints_.DefineSafepoint(masm(), 682 Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
655 kind, arguments, deoptimization_index); 683 kind, arguments, deoptimization_index);
656 for (int i = 0; i < operands->length(); i++) { 684 for (int i = 0; i < operands->length(); i++) {
657 LOperand* pointer = operands->at(i); 685 LOperand* pointer = operands->at(i);
658 if (pointer->IsStackSlot()) { 686 if (pointer->IsStackSlot()) {
659 safepoint.DefinePointerSlot(pointer->index()); 687 safepoint.DefinePointerSlot(pointer->index());
660 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 688 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
661 safepoint.DefinePointerRegister(ToRegister(pointer)); 689 safepoint.DefinePointerRegister(ToRegister(pointer));
662 } 690 }
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 __ bind(&done); 1036 __ bind(&done);
1009 } 1037 }
1010 1038
1011 1039
1012 template<int T> 1040 template<int T>
1013 void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr, 1041 void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
1014 Token::Value op) { 1042 Token::Value op) {
1015 Register left = ToRegister(instr->InputAt(0)); 1043 Register left = ToRegister(instr->InputAt(0));
1016 Register right = ToRegister(instr->InputAt(1)); 1044 Register right = ToRegister(instr->InputAt(1));
1017 1045
1018 __ PushSafepointRegistersAndDoubles(); 1046 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles);
1019 // Move left to r1 and right to r0 for the stub call. 1047 // Move left to r1 and right to r0 for the stub call.
1020 if (left.is(r1)) { 1048 if (left.is(r1)) {
1021 __ Move(r0, right); 1049 __ Move(r0, right);
1022 } else if (left.is(r0) && right.is(r1)) { 1050 } else if (left.is(r0) && right.is(r1)) {
1023 __ Swap(r0, r1, r2); 1051 __ Swap(r0, r1, r2);
1024 } else if (left.is(r0)) { 1052 } else if (left.is(r0)) {
1025 ASSERT(!right.is(r1)); 1053 ASSERT(!right.is(r1));
1026 __ mov(r1, r0); 1054 __ mov(r1, r0);
1027 __ mov(r0, right); 1055 __ mov(r0, right);
1028 } else { 1056 } else {
1029 ASSERT(!left.is(r0) && !right.is(r0)); 1057 ASSERT(!left.is(r0) && !right.is(r0));
1030 __ mov(r0, right); 1058 __ mov(r0, right);
1031 __ mov(r1, left); 1059 __ mov(r1, left);
1032 } 1060 }
1033 TypeRecordingBinaryOpStub stub(op, OVERWRITE_LEFT); 1061 TypeRecordingBinaryOpStub stub(op, OVERWRITE_LEFT);
1034 __ CallStub(&stub); 1062 __ CallStub(&stub);
1035 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), 1063 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
1036 0, 1064 0,
1037 Safepoint::kNoDeoptimizationIndex); 1065 Safepoint::kNoDeoptimizationIndex);
1038 // Overwrite the stored value of r0 with the result of the stub. 1066 // Overwrite the stored value of r0 with the result of the stub.
1039 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); 1067 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0);
1040 __ PopSafepointRegistersAndDoubles();
1041 } 1068 }
1042 1069
1043 1070
1044 void LCodeGen::DoMulI(LMulI* instr) { 1071 void LCodeGen::DoMulI(LMulI* instr) {
1045 Register scratch = scratch0(); 1072 Register scratch = scratch0();
1046 Register left = ToRegister(instr->InputAt(0)); 1073 Register left = ToRegister(instr->InputAt(0));
1047 Register right = EmitLoadRegister(instr->InputAt(1), scratch); 1074 Register right = EmitLoadRegister(instr->InputAt(1), scratch);
1048 1075
1049 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) && 1076 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) &&
1050 !instr->InputAt(1)->IsConstantOperand()) { 1077 !instr->InputAt(1)->IsConstantOperand()) {
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 __ jmp(deferred_stack_check->entry()); 1480 __ jmp(deferred_stack_check->entry());
1454 deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block)); 1481 deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block));
1455 } else { 1482 } else {
1456 __ jmp(chunk_->GetAssemblyLabel(block)); 1483 __ jmp(chunk_->GetAssemblyLabel(block));
1457 } 1484 }
1458 } 1485 }
1459 } 1486 }
1460 1487
1461 1488
1462 void LCodeGen::DoDeferredStackCheck(LGoto* instr) { 1489 void LCodeGen::DoDeferredStackCheck(LGoto* instr) {
1463 __ PushSafepointRegisters(); 1490 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
1464 __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 1491 CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr);
1465 RecordSafepointWithRegisters(
1466 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
1467 __ PopSafepointRegisters();
1468 } 1492 }
1469 1493
1470 1494
1471 void LCodeGen::DoGoto(LGoto* instr) { 1495 void LCodeGen::DoGoto(LGoto* instr) {
1472 class DeferredStackCheck: public LDeferredCode { 1496 class DeferredStackCheck: public LDeferredCode {
1473 public: 1497 public:
1474 DeferredStackCheck(LCodeGen* codegen, LGoto* instr) 1498 DeferredStackCheck(LCodeGen* codegen, LGoto* instr)
1475 : LDeferredCode(codegen), instr_(instr) { } 1499 : LDeferredCode(codegen), instr_(instr) { }
1476 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 1500 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
1477 private: 1501 private:
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
2058 2082
2059 InstanceofStub::Flags flags = InstanceofStub::kNoFlags; 2083 InstanceofStub::Flags flags = InstanceofStub::kNoFlags;
2060 flags = static_cast<InstanceofStub::Flags>( 2084 flags = static_cast<InstanceofStub::Flags>(
2061 flags | InstanceofStub::kArgsInRegisters); 2085 flags | InstanceofStub::kArgsInRegisters);
2062 flags = static_cast<InstanceofStub::Flags>( 2086 flags = static_cast<InstanceofStub::Flags>(
2063 flags | InstanceofStub::kCallSiteInlineCheck); 2087 flags | InstanceofStub::kCallSiteInlineCheck);
2064 flags = static_cast<InstanceofStub::Flags>( 2088 flags = static_cast<InstanceofStub::Flags>(
2065 flags | InstanceofStub::kReturnTrueFalseObject); 2089 flags | InstanceofStub::kReturnTrueFalseObject);
2066 InstanceofStub stub(flags); 2090 InstanceofStub stub(flags);
2067 2091
2068 __ PushSafepointRegisters(); 2092 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2069 2093
2070 // Get the temp register reserved by the instruction. This needs to be r4 as 2094 // Get the temp register reserved by the instruction. This needs to be r4 as
2071 // its slot of the pushing of safepoint registers is used to communicate the 2095 // its slot of the pushing of safepoint registers is used to communicate the
2072 // offset to the location of the map check. 2096 // offset to the location of the map check.
2073 Register temp = ToRegister(instr->TempAt(0)); 2097 Register temp = ToRegister(instr->TempAt(0));
2074 ASSERT(temp.is(r4)); 2098 ASSERT(temp.is(r4));
2075 __ mov(InstanceofStub::right(), Operand(instr->function())); 2099 __ mov(InstanceofStub::right(), Operand(instr->function()));
2076 static const int kAdditionalDelta = 4; 2100 static const int kAdditionalDelta = 4;
2077 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; 2101 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
2078 Label before_push_delta; 2102 Label before_push_delta;
2079 __ bind(&before_push_delta); 2103 __ bind(&before_push_delta);
2080 __ BlockConstPoolFor(kAdditionalDelta); 2104 __ BlockConstPoolFor(kAdditionalDelta);
2081 __ mov(temp, Operand(delta * kPointerSize)); 2105 __ mov(temp, Operand(delta * kPointerSize));
2082 __ StoreToSafepointRegisterSlot(temp, temp); 2106 __ StoreToSafepointRegisterSlot(temp, temp);
2083 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2107 CallCodeGeneric(stub.GetCode(),
2108 RelocInfo::CODE_TARGET,
2109 instr,
2110 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
2084 // Put the result value into the result register slot and 2111 // Put the result value into the result register slot and
2085 // restore all registers. 2112 // restore all registers.
2086 __ StoreToSafepointRegisterSlot(result, result); 2113 __ StoreToSafepointRegisterSlot(result, result);
2087
2088 __ PopSafepointRegisters();
2089 } 2114 }
2090 2115
2091 2116
2092 static Condition ComputeCompareCondition(Token::Value op) { 2117 static Condition ComputeCompareCondition(Token::Value op) {
2093 switch (op) { 2118 switch (op) {
2094 case Token::EQ_STRICT: 2119 case Token::EQ_STRICT:
2095 case Token::EQ: 2120 case Token::EQ:
2096 return eq; 2121 return eq;
2097 case Token::LT: 2122 case Token::LT:
2098 return lt; 2123 return lt;
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
2632 } 2657 }
2633 2658
2634 LPointerMap* pointers = instr->pointer_map(); 2659 LPointerMap* pointers = instr->pointer_map();
2635 RecordPosition(pointers->position()); 2660 RecordPosition(pointers->position());
2636 2661
2637 // Invoke function. 2662 // Invoke function.
2638 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 2663 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
2639 __ Call(ip); 2664 __ Call(ip);
2640 2665
2641 // Setup deoptimization. 2666 // Setup deoptimization.
2642 RegisterLazyDeoptimization(instr); 2667 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT);
2643 2668
2644 // Restore context. 2669 // Restore context.
2645 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2670 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2646 } 2671 }
2647 2672
2648 2673
2649 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 2674 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2650 ASSERT(ToRegister(instr->result()).is(r0)); 2675 ASSERT(ToRegister(instr->result()).is(r0));
2651 __ mov(r1, Operand(instr->function())); 2676 __ mov(r1, Operand(instr->function()));
2652 CallKnownFunction(instr->function(), instr->arity(), instr); 2677 CallKnownFunction(instr->function(), instr->arity(), instr);
(...skipping 17 matching lines...) Expand all
2670 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 2695 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2671 // Check the sign of the argument. If the argument is positive, just 2696 // Check the sign of the argument. If the argument is positive, just
2672 // return it. We do not need to patch the stack since |input| and 2697 // return it. We do not need to patch the stack since |input| and
2673 // |result| are the same register and |input| would be restored 2698 // |result| are the same register and |input| would be restored
2674 // unchanged by popping safepoint registers. 2699 // unchanged by popping safepoint registers.
2675 __ tst(exponent, Operand(HeapNumber::kSignMask)); 2700 __ tst(exponent, Operand(HeapNumber::kSignMask));
2676 __ b(eq, &done); 2701 __ b(eq, &done);
2677 2702
2678 // Input is negative. Reverse its sign. 2703 // Input is negative. Reverse its sign.
2679 // Preserve the value of all registers. 2704 // Preserve the value of all registers.
2680 __ PushSafepointRegisters(); 2705 {
2706 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2681 2707
2682 // Registers were saved at the safepoint, so we can use 2708 // Registers were saved at the safepoint, so we can use
2683 // many scratch registers. 2709 // many scratch registers.
2684 Register tmp1 = input.is(r1) ? r0 : r1; 2710 Register tmp1 = input.is(r1) ? r0 : r1;
2685 Register tmp2 = input.is(r2) ? r0 : r2; 2711 Register tmp2 = input.is(r2) ? r0 : r2;
2686 Register tmp3 = input.is(r3) ? r0 : r3; 2712 Register tmp3 = input.is(r3) ? r0 : r3;
2687 Register tmp4 = input.is(r4) ? r0 : r4; 2713 Register tmp4 = input.is(r4) ? r0 : r4;
2688 2714
2689 // exponent: floating point exponent value. 2715 // exponent: floating point exponent value.
2690 2716
2691 Label allocated, slow; 2717 Label allocated, slow;
2692 __ LoadRoot(tmp4, Heap::kHeapNumberMapRootIndex); 2718 __ LoadRoot(tmp4, Heap::kHeapNumberMapRootIndex);
2693 __ AllocateHeapNumber(tmp1, tmp2, tmp3, tmp4, &slow); 2719 __ AllocateHeapNumber(tmp1, tmp2, tmp3, tmp4, &slow);
2694 __ b(&allocated); 2720 __ b(&allocated);
2695 2721
2696 // Slow case: Call the runtime system to do the number allocation. 2722 // Slow case: Call the runtime system to do the number allocation.
2697 __ bind(&slow); 2723 __ bind(&slow);
2698 2724
2699 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 2725 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
2700 RecordSafepointWithRegisters( 2726 // Set the pointer to the new heap number in tmp.
2701 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); 2727 if (!tmp1.is(r0)) __ mov(tmp1, Operand(r0));
2702 // Set the pointer to the new heap number in tmp. 2728 // Restore input_reg after call to runtime.
2703 if (!tmp1.is(r0)) __ mov(tmp1, Operand(r0)); 2729 __ LoadFromSafepointRegisterSlot(input, input);
2704 // Restore input_reg after call to runtime. 2730 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2705 __ LoadFromSafepointRegisterSlot(input, input);
2706 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2707 2731
2708 __ bind(&allocated); 2732 __ bind(&allocated);
2709 // exponent: floating point exponent value. 2733 // exponent: floating point exponent value.
2710 // tmp1: allocated heap number. 2734 // tmp1: allocated heap number.
2711 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask)); 2735 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask));
2712 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset)); 2736 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset));
2713 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); 2737 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
2714 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 2738 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
2715 2739
2716 __ StoreToSafepointRegisterSlot(tmp1, input); 2740 __ StoreToSafepointRegisterSlot(tmp1, input);
2717 __ PopSafepointRegisters(); 2741 }
2718 2742
2719 __ bind(&done); 2743 __ bind(&done);
2720 } 2744 }
2721 2745
2722 2746
2723 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 2747 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
2724 Register input = ToRegister(instr->InputAt(0)); 2748 Register input = ToRegister(instr->InputAt(0));
2725 __ cmp(input, Operand(0)); 2749 __ cmp(input, Operand(0));
2726 // We can make rsb conditional because the previous cmp instruction 2750 // We can make rsb conditional because the previous cmp instruction
2727 // will clear the V (overflow) flag and rsb won't set this flag 2751 // will clear the V (overflow) flag and rsb won't set this flag
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
3245 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 3269 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
3246 Register string = ToRegister(instr->string()); 3270 Register string = ToRegister(instr->string());
3247 Register result = ToRegister(instr->result()); 3271 Register result = ToRegister(instr->result());
3248 Register scratch = scratch0(); 3272 Register scratch = scratch0();
3249 3273
3250 // TODO(3095996): Get rid of this. For now, we need to make the 3274 // TODO(3095996): Get rid of this. For now, we need to make the
3251 // result register contain a valid pointer because it is already 3275 // result register contain a valid pointer because it is already
3252 // contained in the register pointer map. 3276 // contained in the register pointer map.
3253 __ mov(result, Operand(0)); 3277 __ mov(result, Operand(0));
3254 3278
3255 __ PushSafepointRegisters(); 3279 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3256 __ push(string); 3280 __ push(string);
3257 // Push the index as a smi. This is safe because of the checks in 3281 // Push the index as a smi. This is safe because of the checks in
3258 // DoStringCharCodeAt above. 3282 // DoStringCharCodeAt above.
3259 if (instr->index()->IsConstantOperand()) { 3283 if (instr->index()->IsConstantOperand()) {
3260 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3284 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3261 __ mov(scratch, Operand(Smi::FromInt(const_index))); 3285 __ mov(scratch, Operand(Smi::FromInt(const_index)));
3262 __ push(scratch); 3286 __ push(scratch);
3263 } else { 3287 } else {
3264 Register index = ToRegister(instr->index()); 3288 Register index = ToRegister(instr->index());
3265 __ SmiTag(index); 3289 __ SmiTag(index);
3266 __ push(index); 3290 __ push(index);
3267 } 3291 }
3268 __ CallRuntimeSaveDoubles(Runtime::kStringCharCodeAt); 3292 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
3269 RecordSafepointWithRegisters(
3270 instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex);
3271 if (FLAG_debug_code) { 3293 if (FLAG_debug_code) {
3272 __ AbortIfNotSmi(r0); 3294 __ AbortIfNotSmi(r0);
3273 } 3295 }
3274 __ SmiUntag(r0); 3296 __ SmiUntag(r0);
3275 __ StoreToSafepointRegisterSlot(r0, result); 3297 __ StoreToSafepointRegisterSlot(r0, result);
3276 __ PopSafepointRegisters();
3277 } 3298 }
3278 3299
3279 3300
3280 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 3301 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
3281 class DeferredStringCharFromCode: public LDeferredCode { 3302 class DeferredStringCharFromCode: public LDeferredCode {
3282 public: 3303 public:
3283 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 3304 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
3284 : LDeferredCode(codegen), instr_(instr) { } 3305 : LDeferredCode(codegen), instr_(instr) { }
3285 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } 3306 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); }
3286 private: 3307 private:
(...skipping 22 matching lines...) Expand all
3309 3330
3310 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { 3331 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
3311 Register char_code = ToRegister(instr->char_code()); 3332 Register char_code = ToRegister(instr->char_code());
3312 Register result = ToRegister(instr->result()); 3333 Register result = ToRegister(instr->result());
3313 3334
3314 // TODO(3095996): Get rid of this. For now, we need to make the 3335 // TODO(3095996): Get rid of this. For now, we need to make the
3315 // result register contain a valid pointer because it is already 3336 // result register contain a valid pointer because it is already
3316 // contained in the register pointer map. 3337 // contained in the register pointer map.
3317 __ mov(result, Operand(0)); 3338 __ mov(result, Operand(0));
3318 3339
3319 __ PushSafepointRegisters(); 3340 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3320 __ SmiTag(char_code); 3341 __ SmiTag(char_code);
3321 __ push(char_code); 3342 __ push(char_code);
3322 __ CallRuntimeSaveDoubles(Runtime::kCharFromCode); 3343 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr);
3323 RecordSafepointWithRegisters(
3324 instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex);
3325 __ StoreToSafepointRegisterSlot(r0, result); 3344 __ StoreToSafepointRegisterSlot(r0, result);
3326 __ PopSafepointRegisters();
3327 } 3345 }
3328 3346
3329 3347
3330 void LCodeGen::DoStringLength(LStringLength* instr) { 3348 void LCodeGen::DoStringLength(LStringLength* instr) {
3331 Register string = ToRegister(instr->InputAt(0)); 3349 Register string = ToRegister(instr->InputAt(0));
3332 Register result = ToRegister(instr->result()); 3350 Register result = ToRegister(instr->result());
3333 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); 3351 __ ldr(result, FieldMemOperand(string, String::kLengthOffset));
3334 } 3352 }
3335 3353
3336 3354
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3372 } 3390 }
3373 3391
3374 3392
3375 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 3393 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
3376 Label slow; 3394 Label slow;
3377 Register reg = ToRegister(instr->InputAt(0)); 3395 Register reg = ToRegister(instr->InputAt(0));
3378 DoubleRegister dbl_scratch = d0; 3396 DoubleRegister dbl_scratch = d0;
3379 SwVfpRegister flt_scratch = s0; 3397 SwVfpRegister flt_scratch = s0;
3380 3398
3381 // Preserve the value of all registers. 3399 // Preserve the value of all registers.
3382 __ PushSafepointRegisters(); 3400 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3383 3401
3384 // There was overflow, so bits 30 and 31 of the original integer 3402 // There was overflow, so bits 30 and 31 of the original integer
3385 // disagree. Try to allocate a heap number in new space and store 3403 // disagree. Try to allocate a heap number in new space and store
3386 // the value in there. If that fails, call the runtime system. 3404 // the value in there. If that fails, call the runtime system.
3387 Label done; 3405 Label done;
3388 __ SmiUntag(reg); 3406 __ SmiUntag(reg);
3389 __ eor(reg, reg, Operand(0x80000000)); 3407 __ eor(reg, reg, Operand(0x80000000));
3390 __ vmov(flt_scratch, reg); 3408 __ vmov(flt_scratch, reg);
3391 __ vcvt_f64_s32(dbl_scratch, flt_scratch); 3409 __ vcvt_f64_s32(dbl_scratch, flt_scratch);
3392 if (FLAG_inline_new) { 3410 if (FLAG_inline_new) {
3393 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); 3411 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
3394 __ AllocateHeapNumber(r5, r3, r4, r6, &slow); 3412 __ AllocateHeapNumber(r5, r3, r4, r6, &slow);
3395 if (!reg.is(r5)) __ mov(reg, r5); 3413 if (!reg.is(r5)) __ mov(reg, r5);
3396 __ b(&done); 3414 __ b(&done);
3397 } 3415 }
3398 3416
3399 // Slow case: Call the runtime system to do the number allocation. 3417 // Slow case: Call the runtime system to do the number allocation.
3400 __ bind(&slow); 3418 __ bind(&slow);
3401 3419
3402 // TODO(3095996): Put a valid pointer value in the stack slot where the result 3420 // TODO(3095996): Put a valid pointer value in the stack slot where the result
3403 // register is stored, as this register is in the pointer map, but contains an 3421 // register is stored, as this register is in the pointer map, but contains an
3404 // integer value. 3422 // integer value.
3405 __ mov(ip, Operand(0)); 3423 __ mov(ip, Operand(0));
3406 __ StoreToSafepointRegisterSlot(ip, reg); 3424 __ StoreToSafepointRegisterSlot(ip, reg);
3407 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 3425 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
3408 RecordSafepointWithRegisters(
3409 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
3410 if (!reg.is(r0)) __ mov(reg, r0); 3426 if (!reg.is(r0)) __ mov(reg, r0);
3411 3427
3412 // Done. Put the value in dbl_scratch into the value of the allocated heap 3428 // Done. Put the value in dbl_scratch into the value of the allocated heap
3413 // number. 3429 // number.
3414 __ bind(&done); 3430 __ bind(&done);
3415 __ sub(ip, reg, Operand(kHeapObjectTag)); 3431 __ sub(ip, reg, Operand(kHeapObjectTag));
3416 __ vstr(dbl_scratch, ip, HeapNumber::kValueOffset); 3432 __ vstr(dbl_scratch, ip, HeapNumber::kValueOffset);
3417 __ StoreToSafepointRegisterSlot(reg, reg); 3433 __ StoreToSafepointRegisterSlot(reg, reg);
3418 __ PopSafepointRegisters();
3419 } 3434 }
3420 3435
3421 3436
3422 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 3437 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
3423 class DeferredNumberTagD: public LDeferredCode { 3438 class DeferredNumberTagD: public LDeferredCode {
3424 public: 3439 public:
3425 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 3440 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
3426 : LDeferredCode(codegen), instr_(instr) { } 3441 : LDeferredCode(codegen), instr_(instr) { }
3427 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 3442 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
3428 private: 3443 private:
(...skipping 19 matching lines...) Expand all
3448 } 3463 }
3449 3464
3450 3465
3451 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 3466 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
3452 // TODO(3095996): Get rid of this. For now, we need to make the 3467 // TODO(3095996): Get rid of this. For now, we need to make the
3453 // result register contain a valid pointer because it is already 3468 // result register contain a valid pointer because it is already
3454 // contained in the register pointer map. 3469 // contained in the register pointer map.
3455 Register reg = ToRegister(instr->result()); 3470 Register reg = ToRegister(instr->result());
3456 __ mov(reg, Operand(0)); 3471 __ mov(reg, Operand(0));
3457 3472
3458 __ PushSafepointRegisters(); 3473 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3459 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 3474 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
3460 RecordSafepointWithRegisters(
3461 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
3462 __ StoreToSafepointRegisterSlot(r0, reg); 3475 __ StoreToSafepointRegisterSlot(r0, reg);
3463 __ PopSafepointRegisters();
3464 } 3476 }
3465 3477
3466 3478
3467 void LCodeGen::DoSmiTag(LSmiTag* instr) { 3479 void LCodeGen::DoSmiTag(LSmiTag* instr) {
3468 LOperand* input = instr->InputAt(0); 3480 LOperand* input = instr->InputAt(0);
3469 ASSERT(input->IsRegister() && input->Equals(instr->result())); 3481 ASSERT(input->IsRegister() && input->Equals(instr->result()));
3470 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 3482 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
3471 __ SmiTag(ToRegister(input)); 3483 __ SmiTag(ToRegister(input));
3472 } 3484 }
3473 3485
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
4123 ASSERT(!environment->HasBeenRegistered()); 4135 ASSERT(!environment->HasBeenRegistered());
4124 RegisterEnvironmentForDeoptimization(environment); 4136 RegisterEnvironmentForDeoptimization(environment);
4125 ASSERT(osr_pc_offset_ == -1); 4137 ASSERT(osr_pc_offset_ == -1);
4126 osr_pc_offset_ = masm()->pc_offset(); 4138 osr_pc_offset_ = masm()->pc_offset();
4127 } 4139 }
4128 4140
4129 4141
4130 #undef __ 4142 #undef __
4131 4143
4132 } } // namespace v8::internal 4144 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698