OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved.7 | 1 // Copyright 2012 the V8 project authors. All rights reserved.7 |
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 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 // Nothing to do. | 1040 // Nothing to do. |
1041 } | 1041 } |
1042 | 1042 |
1043 | 1043 |
1044 void LCodeGen::DoCallStub(LCallStub* instr) { | 1044 void LCodeGen::DoCallStub(LCallStub* instr) { |
1045 ASSERT(ToRegister(instr->context()).is(cp)); | 1045 ASSERT(ToRegister(instr->context()).is(cp)); |
1046 ASSERT(ToRegister(instr->result()).is(v0)); | 1046 ASSERT(ToRegister(instr->result()).is(v0)); |
1047 switch (instr->hydrogen()->major_key()) { | 1047 switch (instr->hydrogen()->major_key()) { |
1048 case CodeStub::RegExpExec: { | 1048 case CodeStub::RegExpExec: { |
1049 RegExpExecStub stub(isolate()); | 1049 RegExpExecStub stub(isolate()); |
1050 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1050 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1051 break; | 1051 break; |
1052 } | 1052 } |
1053 case CodeStub::SubString: { | 1053 case CodeStub::SubString: { |
1054 SubStringStub stub(isolate()); | 1054 SubStringStub stub(isolate()); |
1055 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1055 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1056 break; | 1056 break; |
1057 } | 1057 } |
1058 case CodeStub::StringCompare: { | 1058 case CodeStub::StringCompare: { |
1059 StringCompareStub stub(isolate()); | 1059 StringCompareStub stub(isolate()); |
1060 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1060 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1061 break; | 1061 break; |
1062 } | 1062 } |
1063 default: | 1063 default: |
1064 UNREACHABLE(); | 1064 UNREACHABLE(); |
1065 } | 1065 } |
1066 } | 1066 } |
1067 | 1067 |
1068 | 1068 |
1069 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { | 1069 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { |
1070 GenerateOsrPrologue(); | 1070 GenerateOsrPrologue(); |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2005 } | 2005 } |
2006 | 2006 |
2007 | 2007 |
2008 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { | 2008 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { |
2009 ASSERT(ToRegister(instr->context()).is(cp)); | 2009 ASSERT(ToRegister(instr->context()).is(cp)); |
2010 ASSERT(ToRegister(instr->left()).is(a1)); | 2010 ASSERT(ToRegister(instr->left()).is(a1)); |
2011 ASSERT(ToRegister(instr->right()).is(a0)); | 2011 ASSERT(ToRegister(instr->right()).is(a0)); |
2012 ASSERT(ToRegister(instr->result()).is(v0)); | 2012 ASSERT(ToRegister(instr->result()).is(v0)); |
2013 | 2013 |
2014 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); | 2014 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); |
2015 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2015 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
2016 // Other arch use a nop here, to signal that there is no inlined | 2016 // Other arch use a nop here, to signal that there is no inlined |
2017 // patchable code. Mips does not need the nop, since our marker | 2017 // patchable code. Mips does not need the nop, since our marker |
2018 // instruction (andi zero_reg) will never be used in normal code. | 2018 // instruction (andi zero_reg) will never be used in normal code. |
2019 } | 2019 } |
2020 | 2020 |
2021 | 2021 |
2022 template<class InstrType> | 2022 template<class InstrType> |
2023 void LCodeGen::EmitBranch(InstrType instr, | 2023 void LCodeGen::EmitBranch(InstrType instr, |
2024 Condition condition, | 2024 Condition condition, |
2025 Register src1, | 2025 Register src1, |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2647 | 2647 |
2648 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 2648 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { |
2649 ASSERT(ToRegister(instr->context()).is(cp)); | 2649 ASSERT(ToRegister(instr->context()).is(cp)); |
2650 Label true_label, done; | 2650 Label true_label, done; |
2651 ASSERT(ToRegister(instr->left()).is(a0)); // Object is in a0. | 2651 ASSERT(ToRegister(instr->left()).is(a0)); // Object is in a0. |
2652 ASSERT(ToRegister(instr->right()).is(a1)); // Function is in a1. | 2652 ASSERT(ToRegister(instr->right()).is(a1)); // Function is in a1. |
2653 Register result = ToRegister(instr->result()); | 2653 Register result = ToRegister(instr->result()); |
2654 ASSERT(result.is(v0)); | 2654 ASSERT(result.is(v0)); |
2655 | 2655 |
2656 InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters); | 2656 InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters); |
2657 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2657 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
2658 | 2658 |
2659 __ Branch(&true_label, eq, result, Operand(zero_reg)); | 2659 __ Branch(&true_label, eq, result, Operand(zero_reg)); |
2660 __ li(result, Operand(factory()->false_value())); | 2660 __ li(result, Operand(factory()->false_value())); |
2661 __ Branch(&done); | 2661 __ Branch(&done); |
2662 __ bind(&true_label); | 2662 __ bind(&true_label); |
2663 __ li(result, Operand(factory()->true_value())); | 2663 __ li(result, Operand(factory()->true_value())); |
2664 __ bind(&done); | 2664 __ bind(&done); |
2665 } | 2665 } |
2666 | 2666 |
2667 | 2667 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2767 __ li(InstanceofStub::right(), instr->function()); | 2767 __ li(InstanceofStub::right(), instr->function()); |
2768 static const int kAdditionalDelta = 7; | 2768 static const int kAdditionalDelta = 7; |
2769 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; | 2769 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; |
2770 Label before_push_delta; | 2770 Label before_push_delta; |
2771 __ bind(&before_push_delta); | 2771 __ bind(&before_push_delta); |
2772 { | 2772 { |
2773 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); | 2773 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); |
2774 __ li(temp, Operand(delta * kPointerSize), CONSTANT_SIZE); | 2774 __ li(temp, Operand(delta * kPointerSize), CONSTANT_SIZE); |
2775 __ StoreToSafepointRegisterSlot(temp, temp); | 2775 __ StoreToSafepointRegisterSlot(temp, temp); |
2776 } | 2776 } |
2777 CallCodeGeneric(stub.GetCode(isolate()), | 2777 CallCodeGeneric(stub.GetCode(), |
2778 RelocInfo::CODE_TARGET, | 2778 RelocInfo::CODE_TARGET, |
2779 instr, | 2779 instr, |
2780 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 2780 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); |
2781 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); | 2781 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); |
2782 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 2782 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
2783 // Put the result value into the result register slot and | 2783 // Put the result value into the result register slot and |
2784 // restore all registers. | 2784 // restore all registers. |
2785 __ StoreToSafepointRegisterSlot(result, result); | 2785 __ StoreToSafepointRegisterSlot(result, result); |
2786 } | 2786 } |
2787 | 2787 |
(...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3962 } | 3962 } |
3963 | 3963 |
3964 | 3964 |
3965 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 3965 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
3966 ASSERT(ToRegister(instr->context()).is(cp)); | 3966 ASSERT(ToRegister(instr->context()).is(cp)); |
3967 ASSERT(ToRegister(instr->function()).is(a1)); | 3967 ASSERT(ToRegister(instr->function()).is(a1)); |
3968 ASSERT(ToRegister(instr->result()).is(v0)); | 3968 ASSERT(ToRegister(instr->result()).is(v0)); |
3969 | 3969 |
3970 int arity = instr->arity(); | 3970 int arity = instr->arity(); |
3971 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); | 3971 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); |
3972 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3972 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
3973 } | 3973 } |
3974 | 3974 |
3975 | 3975 |
3976 void LCodeGen::DoCallNew(LCallNew* instr) { | 3976 void LCodeGen::DoCallNew(LCallNew* instr) { |
3977 ASSERT(ToRegister(instr->context()).is(cp)); | 3977 ASSERT(ToRegister(instr->context()).is(cp)); |
3978 ASSERT(ToRegister(instr->constructor()).is(a1)); | 3978 ASSERT(ToRegister(instr->constructor()).is(a1)); |
3979 ASSERT(ToRegister(instr->result()).is(v0)); | 3979 ASSERT(ToRegister(instr->result()).is(v0)); |
3980 | 3980 |
3981 __ li(a0, Operand(instr->arity())); | 3981 __ li(a0, Operand(instr->arity())); |
3982 // No cell in a2 for construct type feedback in optimized code | 3982 // No cell in a2 for construct type feedback in optimized code |
3983 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 3983 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
3984 CallConstructStub stub(isolate(), NO_CALL_FUNCTION_FLAGS); | 3984 CallConstructStub stub(isolate(), NO_CALL_FUNCTION_FLAGS); |
3985 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 3985 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
3986 } | 3986 } |
3987 | 3987 |
3988 | 3988 |
3989 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { | 3989 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
3990 ASSERT(ToRegister(instr->context()).is(cp)); | 3990 ASSERT(ToRegister(instr->context()).is(cp)); |
3991 ASSERT(ToRegister(instr->constructor()).is(a1)); | 3991 ASSERT(ToRegister(instr->constructor()).is(a1)); |
3992 ASSERT(ToRegister(instr->result()).is(v0)); | 3992 ASSERT(ToRegister(instr->result()).is(v0)); |
3993 | 3993 |
3994 __ li(a0, Operand(instr->arity())); | 3994 __ li(a0, Operand(instr->arity())); |
3995 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 3995 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
3996 ElementsKind kind = instr->hydrogen()->elements_kind(); | 3996 ElementsKind kind = instr->hydrogen()->elements_kind(); |
3997 AllocationSiteOverrideMode override_mode = | 3997 AllocationSiteOverrideMode override_mode = |
3998 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) | 3998 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) |
3999 ? DISABLE_ALLOCATION_SITES | 3999 ? DISABLE_ALLOCATION_SITES |
4000 : DONT_OVERRIDE; | 4000 : DONT_OVERRIDE; |
4001 | 4001 |
4002 if (instr->arity() == 0) { | 4002 if (instr->arity() == 0) { |
4003 ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); | 4003 ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); |
4004 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4004 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4005 } else if (instr->arity() == 1) { | 4005 } else if (instr->arity() == 1) { |
4006 Label done; | 4006 Label done; |
4007 if (IsFastPackedElementsKind(kind)) { | 4007 if (IsFastPackedElementsKind(kind)) { |
4008 Label packed_case; | 4008 Label packed_case; |
4009 // We might need a change here, | 4009 // We might need a change here, |
4010 // look at the first argument. | 4010 // look at the first argument. |
4011 __ lw(t1, MemOperand(sp, 0)); | 4011 __ lw(t1, MemOperand(sp, 0)); |
4012 __ Branch(&packed_case, eq, t1, Operand(zero_reg)); | 4012 __ Branch(&packed_case, eq, t1, Operand(zero_reg)); |
4013 | 4013 |
4014 ElementsKind holey_kind = GetHoleyElementsKind(kind); | 4014 ElementsKind holey_kind = GetHoleyElementsKind(kind); |
4015 ArraySingleArgumentConstructorStub stub(isolate(), | 4015 ArraySingleArgumentConstructorStub stub(isolate(), |
4016 holey_kind, | 4016 holey_kind, |
4017 override_mode); | 4017 override_mode); |
4018 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4018 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4019 __ jmp(&done); | 4019 __ jmp(&done); |
4020 __ bind(&packed_case); | 4020 __ bind(&packed_case); |
4021 } | 4021 } |
4022 | 4022 |
4023 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); | 4023 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); |
4024 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4024 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4025 __ bind(&done); | 4025 __ bind(&done); |
4026 } else { | 4026 } else { |
4027 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); | 4027 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); |
4028 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4028 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4029 } | 4029 } |
4030 } | 4030 } |
4031 | 4031 |
4032 | 4032 |
4033 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 4033 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
4034 CallRuntime(instr->function(), instr->arity(), instr); | 4034 CallRuntime(instr->function(), instr->arity(), instr); |
4035 } | 4035 } |
4036 | 4036 |
4037 | 4037 |
4038 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { | 4038 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4452 } | 4452 } |
4453 | 4453 |
4454 | 4454 |
4455 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4455 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
4456 ASSERT(ToRegister(instr->context()).is(cp)); | 4456 ASSERT(ToRegister(instr->context()).is(cp)); |
4457 ASSERT(ToRegister(instr->left()).is(a1)); | 4457 ASSERT(ToRegister(instr->left()).is(a1)); |
4458 ASSERT(ToRegister(instr->right()).is(a0)); | 4458 ASSERT(ToRegister(instr->right()).is(a0)); |
4459 StringAddStub stub(isolate(), | 4459 StringAddStub stub(isolate(), |
4460 instr->hydrogen()->flags(), | 4460 instr->hydrogen()->flags(), |
4461 instr->hydrogen()->pretenure_flag()); | 4461 instr->hydrogen()->pretenure_flag()); |
4462 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4462 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
4463 } | 4463 } |
4464 | 4464 |
4465 | 4465 |
4466 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 4466 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
4467 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { | 4467 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { |
4468 public: | 4468 public: |
4469 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 4469 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
4470 : LDeferredCode(codegen), instr_(instr) { } | 4470 : LDeferredCode(codegen), instr_(instr) { } |
4471 virtual void Generate() V8_OVERRIDE { | 4471 virtual void Generate() V8_OVERRIDE { |
4472 codegen()->DoDeferredStringCharCodeAt(instr_); | 4472 codegen()->DoDeferredStringCharCodeAt(instr_); |
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5452 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 5452 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
5453 ASSERT(ToRegister(instr->context()).is(cp)); | 5453 ASSERT(ToRegister(instr->context()).is(cp)); |
5454 // Use the fast case closure allocation code that allocates in new | 5454 // Use the fast case closure allocation code that allocates in new |
5455 // space for nested functions that don't need literals cloning. | 5455 // space for nested functions that don't need literals cloning. |
5456 bool pretenure = instr->hydrogen()->pretenure(); | 5456 bool pretenure = instr->hydrogen()->pretenure(); |
5457 if (!pretenure && instr->hydrogen()->has_no_literals()) { | 5457 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
5458 FastNewClosureStub stub(isolate(), | 5458 FastNewClosureStub stub(isolate(), |
5459 instr->hydrogen()->strict_mode(), | 5459 instr->hydrogen()->strict_mode(), |
5460 instr->hydrogen()->is_generator()); | 5460 instr->hydrogen()->is_generator()); |
5461 __ li(a2, Operand(instr->hydrogen()->shared_info())); | 5461 __ li(a2, Operand(instr->hydrogen()->shared_info())); |
5462 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5462 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
5463 } else { | 5463 } else { |
5464 __ li(a2, Operand(instr->hydrogen()->shared_info())); | 5464 __ li(a2, Operand(instr->hydrogen()->shared_info())); |
5465 __ li(a1, Operand(pretenure ? factory()->true_value() | 5465 __ li(a1, Operand(pretenure ? factory()->true_value() |
5466 : factory()->false_value())); | 5466 : factory()->false_value())); |
5467 __ Push(cp, a2, a1); | 5467 __ Push(cp, a2, a1); |
5468 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); | 5468 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); |
5469 } | 5469 } |
5470 } | 5470 } |
5471 | 5471 |
5472 | 5472 |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5897 __ lw(result, FieldMemOperand(scratch, | 5897 __ lw(result, FieldMemOperand(scratch, |
5898 FixedArray::kHeaderSize - kPointerSize)); | 5898 FixedArray::kHeaderSize - kPointerSize)); |
5899 __ bind(deferred->exit()); | 5899 __ bind(deferred->exit()); |
5900 __ bind(&done); | 5900 __ bind(&done); |
5901 } | 5901 } |
5902 | 5902 |
5903 | 5903 |
5904 #undef __ | 5904 #undef __ |
5905 | 5905 |
5906 } } // namespace v8::internal | 5906 } } // namespace v8::internal |
OLD | NEW |