| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 ASSERT(is_done()); | 870 ASSERT(is_done()); |
| 871 safepoints_.Emit(masm(), GetStackSlotCount()); | 871 safepoints_.Emit(masm(), GetStackSlotCount()); |
| 872 return !is_aborted(); | 872 return !is_aborted(); |
| 873 } | 873 } |
| 874 | 874 |
| 875 | 875 |
| 876 void LCodeGen::FinishCode(Handle<Code> code) { | 876 void LCodeGen::FinishCode(Handle<Code> code) { |
| 877 ASSERT(is_done()); | 877 ASSERT(is_done()); |
| 878 code->set_stack_slots(GetStackSlotCount()); | 878 code->set_stack_slots(GetStackSlotCount()); |
| 879 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); | 879 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); |
| 880 if (FLAG_weak_embedded_maps_in_optimized_code) { | 880 RegisterDependentCodeForEmbeddedMaps(code); |
| 881 RegisterDependentCodeForEmbeddedMaps(code); | |
| 882 } | |
| 883 PopulateDeoptimizationData(code); | 881 PopulateDeoptimizationData(code); |
| 884 info()->CommitDependencies(code); | 882 info()->CommitDependencies(code); |
| 885 } | 883 } |
| 886 | 884 |
| 887 | 885 |
| 888 void LCodeGen::Abort(BailoutReason reason) { | 886 void LCodeGen::Abort(BailoutReason reason) { |
| 889 info()->set_bailout_reason(reason); | 887 info()->set_bailout_reason(reason); |
| 890 status_ = ABORTED; | 888 status_ = ABORTED; |
| 891 } | 889 } |
| 892 | 890 |
| 893 | 891 |
| 894 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { | |
| 895 ZoneList<Handle<Map> > maps(1, zone()); | |
| 896 ZoneList<Handle<JSObject> > objects(1, zone()); | |
| 897 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | |
| 898 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { | |
| 899 if (Code::IsWeakEmbeddedObject(code->kind(), it.rinfo()->target_object())) { | |
| 900 if (it.rinfo()->target_object()->IsMap()) { | |
| 901 Handle<Map> map(Map::cast(it.rinfo()->target_object())); | |
| 902 maps.Add(map, zone()); | |
| 903 } else if (it.rinfo()->target_object()->IsJSObject()) { | |
| 904 Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object())); | |
| 905 objects.Add(object, zone()); | |
| 906 } | |
| 907 } | |
| 908 } | |
| 909 #ifdef VERIFY_HEAP | |
| 910 // This disables verification of weak embedded objects after full GC. | |
| 911 // AddDependentCode can cause a GC, which would observe the state where | |
| 912 // this code is not yet in the depended code lists of the embedded maps. | |
| 913 NoWeakObjectVerificationScope disable_verification_of_embedded_objects; | |
| 914 #endif | |
| 915 for (int i = 0; i < maps.length(); i++) { | |
| 916 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code); | |
| 917 } | |
| 918 for (int i = 0; i < objects.length(); i++) { | |
| 919 AddWeakObjectToCodeDependency(isolate()->heap(), objects.at(i), code); | |
| 920 } | |
| 921 } | |
| 922 | |
| 923 | |
| 924 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { | 892 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { |
| 925 int length = deoptimizations_.length(); | 893 int length = deoptimizations_.length(); |
| 926 if (length == 0) return; | 894 if (length == 0) return; |
| 927 | 895 |
| 928 Handle<DeoptimizationInputData> data = | 896 Handle<DeoptimizationInputData> data = |
| 929 factory()->NewDeoptimizationInputData(length, TENURED); | 897 factory()->NewDeoptimizationInputData(length, TENURED); |
| 930 | 898 |
| 931 Handle<ByteArray> translations = | 899 Handle<ByteArray> translations = |
| 932 translations_.CreateByteArray(isolate()->factory()); | 900 translations_.CreateByteArray(isolate()->factory()); |
| 933 data->SetTranslationByteArray(*translations); | 901 data->SetTranslationByteArray(*translations); |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 break; | 1632 break; |
| 1665 } | 1633 } |
| 1666 } | 1634 } |
| 1667 | 1635 |
| 1668 | 1636 |
| 1669 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { | 1637 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { |
| 1670 ASSERT(ToRegister(instr->left()).is(x1)); | 1638 ASSERT(ToRegister(instr->left()).is(x1)); |
| 1671 ASSERT(ToRegister(instr->right()).is(x0)); | 1639 ASSERT(ToRegister(instr->right()).is(x0)); |
| 1672 ASSERT(ToRegister(instr->result()).is(x0)); | 1640 ASSERT(ToRegister(instr->result()).is(x0)); |
| 1673 | 1641 |
| 1674 BinaryOpStub stub(instr->op(), NO_OVERWRITE); | 1642 BinaryOpICStub stub(instr->op(), NO_OVERWRITE); |
| 1675 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1643 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1676 } | 1644 } |
| 1677 | 1645 |
| 1678 | 1646 |
| 1679 void LCodeGen::DoBitI(LBitI* instr) { | 1647 void LCodeGen::DoBitI(LBitI* instr) { |
| 1680 Register result = ToRegister32(instr->result()); | 1648 Register result = ToRegister32(instr->result()); |
| 1681 Register left = ToRegister32(instr->left()); | 1649 Register left = ToRegister32(instr->left()); |
| 1682 Operand right = ToOperand32U(instr->right()); | 1650 Operand right = ToOperand32U(instr->right()); |
| 1683 | 1651 |
| 1684 switch (instr->op()) { | 1652 switch (instr->op()) { |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1927 __ SetCallKind(call_kind_reg, call_kind); | 1895 __ SetCallKind(call_kind_reg, call_kind); |
| 1928 __ Ldr(x10, FieldMemOperand(function_reg, JSFunction::kCodeEntryOffset)); | 1896 __ Ldr(x10, FieldMemOperand(function_reg, JSFunction::kCodeEntryOffset)); |
| 1929 __ Call(x10); | 1897 __ Call(x10); |
| 1930 | 1898 |
| 1931 // Set up deoptimization. | 1899 // Set up deoptimization. |
| 1932 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 1900 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
| 1933 } else { | 1901 } else { |
| 1934 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 1902 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 1935 ParameterCount count(arity); | 1903 ParameterCount count(arity); |
| 1936 ParameterCount expected(formal_parameter_count); | 1904 ParameterCount expected(formal_parameter_count); |
| 1937 __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator, | 1905 __ InvokeFunction( |
| 1938 call_kind, function_reg); | 1906 function_reg, expected, count, CALL_FUNCTION, generator, call_kind); |
| 1939 } | 1907 } |
| 1940 | 1908 |
| 1941 // Restore context. | 1909 // Restore context. |
| 1942 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1910 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1943 } | 1911 } |
| 1944 | 1912 |
| 1945 | 1913 |
| 1946 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 1914 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
| 1947 ASSERT(ToRegister(instr->result()).is(x0)); | 1915 ASSERT(ToRegister(instr->result()).is(x0)); |
| 1948 CallKnownFunction(instr->hydrogen()->function(), | 1916 CallKnownFunction(instr->hydrogen()->function(), |
| (...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2928 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); | 2896 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); |
| 2929 } | 2897 } |
| 2930 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); | 2898 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); |
| 2931 EmitBranch(instr, BranchCondition(instr->hydrogen())); | 2899 EmitBranch(instr, BranchCondition(instr->hydrogen())); |
| 2932 } | 2900 } |
| 2933 | 2901 |
| 2934 | 2902 |
| 2935 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { | 2903 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |
| 2936 Register result = ToRegister(instr->result()); | 2904 Register result = ToRegister(instr->result()); |
| 2937 Register base = ToRegister(instr->base_object()); | 2905 Register base = ToRegister(instr->base_object()); |
| 2938 __ Add(result, base, instr->offset()); | 2906 __ Add(result, base, ToOperand(instr->offset())); |
| 2939 } | 2907 } |
| 2940 | 2908 |
| 2941 | 2909 |
| 2942 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 2910 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { |
| 2943 // Assert that the arguments are in the registers expected by InstanceofStub. | 2911 // Assert that the arguments are in the registers expected by InstanceofStub. |
| 2944 ASSERT(ToRegister(instr->left()).Is(InstanceofStub::left())); | 2912 ASSERT(ToRegister(instr->left()).Is(InstanceofStub::left())); |
| 2945 ASSERT(ToRegister(instr->right()).Is(InstanceofStub::right())); | 2913 ASSERT(ToRegister(instr->right()).Is(InstanceofStub::right())); |
| 2946 | 2914 |
| 2947 InstanceofStub stub(InstanceofStub::kArgsInRegisters); | 2915 InstanceofStub stub(InstanceofStub::kArgsInRegisters); |
| 2948 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2916 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| (...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3725 __ Mov(result_bits, double_to_rawbits(0x80000000)); | 3693 __ Mov(result_bits, double_to_rawbits(0x80000000)); |
| 3726 __ B(deferred->allocation_entry()); | 3694 __ B(deferred->allocation_entry()); |
| 3727 | 3695 |
| 3728 __ Bind(deferred->exit()); | 3696 __ Bind(deferred->exit()); |
| 3729 __ Str(result_bits, FieldMemOperand(result, HeapNumber::kValueOffset)); | 3697 __ Str(result_bits, FieldMemOperand(result, HeapNumber::kValueOffset)); |
| 3730 | 3698 |
| 3731 __ Bind(&done); | 3699 __ Bind(&done); |
| 3732 } | 3700 } |
| 3733 | 3701 |
| 3734 | 3702 |
| 3735 void LCodeGen::DoMathCos(LMathCos* instr) { | |
| 3736 ASSERT(ToDoubleRegister(instr->result()).is(d0)); | |
| 3737 TranscendentalCacheStub stub(TranscendentalCache::COS, | |
| 3738 TranscendentalCacheStub::UNTAGGED); | |
| 3739 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 3740 ASSERT(ToDoubleRegister(instr->result()).Is(d0)); | |
| 3741 } | |
| 3742 | |
| 3743 | |
| 3744 void LCodeGen::DoMathExp(LMathExp* instr) { | 3703 void LCodeGen::DoMathExp(LMathExp* instr) { |
| 3745 DoubleRegister input = ToDoubleRegister(instr->value()); | 3704 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 3746 DoubleRegister result = ToDoubleRegister(instr->result()); | 3705 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3747 DoubleRegister double_temp1 = ToDoubleRegister(instr->double_temp1()); | 3706 DoubleRegister double_temp1 = ToDoubleRegister(instr->double_temp1()); |
| 3748 DoubleRegister double_temp2 = double_scratch(); | 3707 DoubleRegister double_temp2 = double_scratch(); |
| 3749 Register temp1 = ToRegister(instr->temp1()); | 3708 Register temp1 = ToRegister(instr->temp1()); |
| 3750 Register temp2 = ToRegister(instr->temp2()); | 3709 Register temp2 = ToRegister(instr->temp2()); |
| 3751 Register temp3 = ToRegister(instr->temp3()); | 3710 Register temp3 = ToRegister(instr->temp3()); |
| 3752 | 3711 |
| 3753 MathExpGenerator::EmitMathExp(masm(), input, result, | 3712 MathExpGenerator::EmitMathExp(masm(), input, result, |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3953 // * the input was NaN | 3912 // * the input was NaN |
| 3954 // * the result is not representable using a 32-bit integer. | 3913 // * the result is not representable using a 32-bit integer. |
| 3955 __ Fcmp(input, 0.0); | 3914 __ Fcmp(input, 0.0); |
| 3956 __ Ccmp(result, Operand(result.W(), SXTW), NoFlag, vc); | 3915 __ Ccmp(result, Operand(result.W(), SXTW), NoFlag, vc); |
| 3957 __ B(ne, &deopt); | 3916 __ B(ne, &deopt); |
| 3958 | 3917 |
| 3959 __ Bind(&done); | 3918 __ Bind(&done); |
| 3960 } | 3919 } |
| 3961 | 3920 |
| 3962 | 3921 |
| 3963 void LCodeGen::DoMathSin(LMathSin* instr) { | |
| 3964 ASSERT(ToDoubleRegister(instr->result()).is(d0)); | |
| 3965 TranscendentalCacheStub stub(TranscendentalCache::SIN, | |
| 3966 TranscendentalCacheStub::UNTAGGED); | |
| 3967 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 3968 ASSERT(ToDoubleRegister(instr->result()).Is(d0)); | |
| 3969 } | |
| 3970 | |
| 3971 | |
| 3972 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { | 3922 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { |
| 3973 DoubleRegister input = ToDoubleRegister(instr->value()); | 3923 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 3974 DoubleRegister result = ToDoubleRegister(instr->result()); | 3924 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3975 __ Fsqrt(result, input); | 3925 __ Fsqrt(result, input); |
| 3976 } | 3926 } |
| 3977 | 3927 |
| 3978 | 3928 |
| 3979 void LCodeGen::DoMathTan(LMathTan* instr) { | |
| 3980 ASSERT(ToDoubleRegister(instr->result()).is(d0)); | |
| 3981 TranscendentalCacheStub stub(TranscendentalCache::TAN, | |
| 3982 TranscendentalCacheStub::UNTAGGED); | |
| 3983 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 3984 ASSERT(ToDoubleRegister(instr->result()).Is(d0)); | |
| 3985 } | |
| 3986 | |
| 3987 | |
| 3988 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 3929 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
| 3989 HMathMinMax::Operation op = instr->hydrogen()->operation(); | 3930 HMathMinMax::Operation op = instr->hydrogen()->operation(); |
| 3990 if (instr->hydrogen()->representation().IsInteger32()) { | 3931 if (instr->hydrogen()->representation().IsInteger32()) { |
| 3991 Register result = ToRegister32(instr->result()); | 3932 Register result = ToRegister32(instr->result()); |
| 3992 Register left = ToRegister32(instr->left()); | 3933 Register left = ToRegister32(instr->left()); |
| 3993 Operand right = ToOperand32I(instr->right()); | 3934 Operand right = ToOperand32I(instr->right()); |
| 3994 | 3935 |
| 3995 __ Cmp(left, right); | 3936 __ Cmp(left, right); |
| 3996 __ Csel(result, left, right, (op == HMathMinMax::kMathMax) ? ge : le); | 3937 __ Csel(result, left, right, (op == HMathMinMax::kMathMax) ? ge : le); |
| 3997 } else if (instr->hydrogen()->representation().IsSmi()) { | 3938 } else if (instr->hydrogen()->representation().IsSmi()) { |
| (...skipping 1686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5684 __ Bind(&out_of_object); | 5625 __ Bind(&out_of_object); |
| 5685 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5626 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 5686 // Index is equal to negated out of object property index plus 1. | 5627 // Index is equal to negated out of object property index plus 1. |
| 5687 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5628 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 5688 __ Ldr(result, FieldMemOperand(result, | 5629 __ Ldr(result, FieldMemOperand(result, |
| 5689 FixedArray::kHeaderSize - kPointerSize)); | 5630 FixedArray::kHeaderSize - kPointerSize)); |
| 5690 __ Bind(&done); | 5631 __ Bind(&done); |
| 5691 } | 5632 } |
| 5692 | 5633 |
| 5693 } } // namespace v8::internal | 5634 } } // namespace v8::internal |
| OLD | NEW |