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 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 // Nothing to do. | 983 // Nothing to do. |
984 } | 984 } |
985 | 985 |
986 | 986 |
987 void LCodeGen::DoCallStub(LCallStub* instr) { | 987 void LCodeGen::DoCallStub(LCallStub* instr) { |
988 ASSERT(ToRegister(instr->context()).is(rsi)); | 988 ASSERT(ToRegister(instr->context()).is(rsi)); |
989 ASSERT(ToRegister(instr->result()).is(rax)); | 989 ASSERT(ToRegister(instr->result()).is(rax)); |
990 switch (instr->hydrogen()->major_key()) { | 990 switch (instr->hydrogen()->major_key()) { |
991 case CodeStub::RegExpExec: { | 991 case CodeStub::RegExpExec: { |
992 RegExpExecStub stub(isolate()); | 992 RegExpExecStub stub(isolate()); |
993 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 993 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
994 break; | 994 break; |
995 } | 995 } |
996 case CodeStub::SubString: { | 996 case CodeStub::SubString: { |
997 SubStringStub stub(isolate()); | 997 SubStringStub stub(isolate()); |
998 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 998 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
999 break; | 999 break; |
1000 } | 1000 } |
1001 case CodeStub::StringCompare: { | 1001 case CodeStub::StringCompare: { |
1002 StringCompareStub stub(isolate()); | 1002 StringCompareStub stub(isolate()); |
1003 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1003 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1004 break; | 1004 break; |
1005 } | 1005 } |
1006 default: | 1006 default: |
1007 UNREACHABLE(); | 1007 UNREACHABLE(); |
1008 } | 1008 } |
1009 } | 1009 } |
1010 | 1010 |
1011 | 1011 |
1012 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { | 1012 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { |
1013 GenerateOsrPrologue(); | 1013 GenerateOsrPrologue(); |
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2023 } | 2023 } |
2024 | 2024 |
2025 | 2025 |
2026 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { | 2026 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { |
2027 ASSERT(ToRegister(instr->context()).is(rsi)); | 2027 ASSERT(ToRegister(instr->context()).is(rsi)); |
2028 ASSERT(ToRegister(instr->left()).is(rdx)); | 2028 ASSERT(ToRegister(instr->left()).is(rdx)); |
2029 ASSERT(ToRegister(instr->right()).is(rax)); | 2029 ASSERT(ToRegister(instr->right()).is(rax)); |
2030 ASSERT(ToRegister(instr->result()).is(rax)); | 2030 ASSERT(ToRegister(instr->result()).is(rax)); |
2031 | 2031 |
2032 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); | 2032 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); |
2033 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2033 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
2034 } | 2034 } |
2035 | 2035 |
2036 | 2036 |
2037 template<class InstrType> | 2037 template<class InstrType> |
2038 void LCodeGen::EmitBranch(InstrType instr, Condition cc) { | 2038 void LCodeGen::EmitBranch(InstrType instr, Condition cc) { |
2039 int left_block = instr->TrueDestination(chunk_); | 2039 int left_block = instr->TrueDestination(chunk_); |
2040 int right_block = instr->FalseDestination(chunk_); | 2040 int right_block = instr->FalseDestination(chunk_); |
2041 | 2041 |
2042 int next_block = GetNextEmittedBlock(); | 2042 int next_block = GetNextEmittedBlock(); |
2043 | 2043 |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2619 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); | 2619 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); |
2620 EmitBranch(instr, equal); | 2620 EmitBranch(instr, equal); |
2621 } | 2621 } |
2622 | 2622 |
2623 | 2623 |
2624 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 2624 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { |
2625 ASSERT(ToRegister(instr->context()).is(rsi)); | 2625 ASSERT(ToRegister(instr->context()).is(rsi)); |
2626 InstanceofStub stub(isolate(), InstanceofStub::kNoFlags); | 2626 InstanceofStub stub(isolate(), InstanceofStub::kNoFlags); |
2627 __ Push(ToRegister(instr->left())); | 2627 __ Push(ToRegister(instr->left())); |
2628 __ Push(ToRegister(instr->right())); | 2628 __ Push(ToRegister(instr->right())); |
2629 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2629 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
2630 Label true_value, done; | 2630 Label true_value, done; |
2631 __ testp(rax, rax); | 2631 __ testp(rax, rax); |
2632 __ j(zero, &true_value, Label::kNear); | 2632 __ j(zero, &true_value, Label::kNear); |
2633 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); | 2633 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); |
2634 __ jmp(&done, Label::kNear); | 2634 __ jmp(&done, Label::kNear); |
2635 __ bind(&true_value); | 2635 __ bind(&true_value); |
2636 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); | 2636 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); |
2637 __ bind(&done); | 2637 __ bind(&done); |
2638 } | 2638 } |
2639 | 2639 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2717 static const int kAdditionalDelta = 10; | 2717 static const int kAdditionalDelta = 10; |
2718 int delta = | 2718 int delta = |
2719 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; | 2719 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; |
2720 ASSERT(delta >= 0); | 2720 ASSERT(delta >= 0); |
2721 __ PushImm32(delta); | 2721 __ PushImm32(delta); |
2722 | 2722 |
2723 // We are pushing three values on the stack but recording a | 2723 // We are pushing three values on the stack but recording a |
2724 // safepoint with two arguments because stub is going to | 2724 // safepoint with two arguments because stub is going to |
2725 // remove the third argument from the stack before jumping | 2725 // remove the third argument from the stack before jumping |
2726 // to instanceof builtin on the slow path. | 2726 // to instanceof builtin on the slow path. |
2727 CallCodeGeneric(stub.GetCode(isolate()), | 2727 CallCodeGeneric(stub.GetCode(), |
2728 RelocInfo::CODE_TARGET, | 2728 RelocInfo::CODE_TARGET, |
2729 instr, | 2729 instr, |
2730 RECORD_SAFEPOINT_WITH_REGISTERS, | 2730 RECORD_SAFEPOINT_WITH_REGISTERS, |
2731 2); | 2731 2); |
2732 ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check)); | 2732 ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check)); |
2733 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); | 2733 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); |
2734 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 2734 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
2735 // Move result to a register that survives the end of the | 2735 // Move result to a register that survives the end of the |
2736 // PushSafepointRegisterScope. | 2736 // PushSafepointRegisterScope. |
2737 __ movp(kScratchRegister, rax); | 2737 __ movp(kScratchRegister, rax); |
(...skipping 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3902 } | 3902 } |
3903 | 3903 |
3904 | 3904 |
3905 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 3905 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
3906 ASSERT(ToRegister(instr->context()).is(rsi)); | 3906 ASSERT(ToRegister(instr->context()).is(rsi)); |
3907 ASSERT(ToRegister(instr->function()).is(rdi)); | 3907 ASSERT(ToRegister(instr->function()).is(rdi)); |
3908 ASSERT(ToRegister(instr->result()).is(rax)); | 3908 ASSERT(ToRegister(instr->result()).is(rax)); |
3909 | 3909 |
3910 int arity = instr->arity(); | 3910 int arity = instr->arity(); |
3911 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); | 3911 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); |
3912 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3912 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
3913 } | 3913 } |
3914 | 3914 |
3915 | 3915 |
3916 void LCodeGen::DoCallNew(LCallNew* instr) { | 3916 void LCodeGen::DoCallNew(LCallNew* instr) { |
3917 ASSERT(ToRegister(instr->context()).is(rsi)); | 3917 ASSERT(ToRegister(instr->context()).is(rsi)); |
3918 ASSERT(ToRegister(instr->constructor()).is(rdi)); | 3918 ASSERT(ToRegister(instr->constructor()).is(rdi)); |
3919 ASSERT(ToRegister(instr->result()).is(rax)); | 3919 ASSERT(ToRegister(instr->result()).is(rax)); |
3920 | 3920 |
3921 __ Set(rax, instr->arity()); | 3921 __ Set(rax, instr->arity()); |
3922 // No cell in ebx for construct type feedback in optimized code | 3922 // No cell in ebx for construct type feedback in optimized code |
3923 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 3923 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
3924 CallConstructStub stub(isolate(), NO_CALL_FUNCTION_FLAGS); | 3924 CallConstructStub stub(isolate(), NO_CALL_FUNCTION_FLAGS); |
3925 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 3925 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
3926 } | 3926 } |
3927 | 3927 |
3928 | 3928 |
3929 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { | 3929 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
3930 ASSERT(ToRegister(instr->context()).is(rsi)); | 3930 ASSERT(ToRegister(instr->context()).is(rsi)); |
3931 ASSERT(ToRegister(instr->constructor()).is(rdi)); | 3931 ASSERT(ToRegister(instr->constructor()).is(rdi)); |
3932 ASSERT(ToRegister(instr->result()).is(rax)); | 3932 ASSERT(ToRegister(instr->result()).is(rax)); |
3933 | 3933 |
3934 __ Set(rax, instr->arity()); | 3934 __ Set(rax, instr->arity()); |
3935 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 3935 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
3936 ElementsKind kind = instr->hydrogen()->elements_kind(); | 3936 ElementsKind kind = instr->hydrogen()->elements_kind(); |
3937 AllocationSiteOverrideMode override_mode = | 3937 AllocationSiteOverrideMode override_mode = |
3938 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) | 3938 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) |
3939 ? DISABLE_ALLOCATION_SITES | 3939 ? DISABLE_ALLOCATION_SITES |
3940 : DONT_OVERRIDE; | 3940 : DONT_OVERRIDE; |
3941 | 3941 |
3942 if (instr->arity() == 0) { | 3942 if (instr->arity() == 0) { |
3943 ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); | 3943 ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); |
3944 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 3944 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
3945 } else if (instr->arity() == 1) { | 3945 } else if (instr->arity() == 1) { |
3946 Label done; | 3946 Label done; |
3947 if (IsFastPackedElementsKind(kind)) { | 3947 if (IsFastPackedElementsKind(kind)) { |
3948 Label packed_case; | 3948 Label packed_case; |
3949 // We might need a change here | 3949 // We might need a change here |
3950 // look at the first argument | 3950 // look at the first argument |
3951 __ movp(rcx, Operand(rsp, 0)); | 3951 __ movp(rcx, Operand(rsp, 0)); |
3952 __ testp(rcx, rcx); | 3952 __ testp(rcx, rcx); |
3953 __ j(zero, &packed_case, Label::kNear); | 3953 __ j(zero, &packed_case, Label::kNear); |
3954 | 3954 |
3955 ElementsKind holey_kind = GetHoleyElementsKind(kind); | 3955 ElementsKind holey_kind = GetHoleyElementsKind(kind); |
3956 ArraySingleArgumentConstructorStub stub(isolate(), | 3956 ArraySingleArgumentConstructorStub stub(isolate(), |
3957 holey_kind, | 3957 holey_kind, |
3958 override_mode); | 3958 override_mode); |
3959 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 3959 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
3960 __ jmp(&done, Label::kNear); | 3960 __ jmp(&done, Label::kNear); |
3961 __ bind(&packed_case); | 3961 __ bind(&packed_case); |
3962 } | 3962 } |
3963 | 3963 |
3964 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); | 3964 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); |
3965 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 3965 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
3966 __ bind(&done); | 3966 __ bind(&done); |
3967 } else { | 3967 } else { |
3968 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); | 3968 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); |
3969 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 3969 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
3970 } | 3970 } |
3971 } | 3971 } |
3972 | 3972 |
3973 | 3973 |
3974 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 3974 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
3975 ASSERT(ToRegister(instr->context()).is(rsi)); | 3975 ASSERT(ToRegister(instr->context()).is(rsi)); |
3976 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); | 3976 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); |
3977 } | 3977 } |
3978 | 3978 |
3979 | 3979 |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4431 } | 4431 } |
4432 | 4432 |
4433 | 4433 |
4434 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4434 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
4435 ASSERT(ToRegister(instr->context()).is(rsi)); | 4435 ASSERT(ToRegister(instr->context()).is(rsi)); |
4436 ASSERT(ToRegister(instr->left()).is(rdx)); | 4436 ASSERT(ToRegister(instr->left()).is(rdx)); |
4437 ASSERT(ToRegister(instr->right()).is(rax)); | 4437 ASSERT(ToRegister(instr->right()).is(rax)); |
4438 StringAddStub stub(isolate(), | 4438 StringAddStub stub(isolate(), |
4439 instr->hydrogen()->flags(), | 4439 instr->hydrogen()->flags(), |
4440 instr->hydrogen()->pretenure_flag()); | 4440 instr->hydrogen()->pretenure_flag()); |
4441 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4441 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
4442 } | 4442 } |
4443 | 4443 |
4444 | 4444 |
4445 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 4445 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
4446 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { | 4446 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { |
4447 public: | 4447 public: |
4448 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 4448 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
4449 : LDeferredCode(codegen), instr_(instr) { } | 4449 : LDeferredCode(codegen), instr_(instr) { } |
4450 virtual void Generate() V8_OVERRIDE { | 4450 virtual void Generate() V8_OVERRIDE { |
4451 codegen()->DoDeferredStringCharCodeAt(instr_); | 4451 codegen()->DoDeferredStringCharCodeAt(instr_); |
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5314 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 5314 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
5315 ASSERT(ToRegister(instr->context()).is(rsi)); | 5315 ASSERT(ToRegister(instr->context()).is(rsi)); |
5316 // Use the fast case closure allocation code that allocates in new | 5316 // Use the fast case closure allocation code that allocates in new |
5317 // space for nested functions that don't need literals cloning. | 5317 // space for nested functions that don't need literals cloning. |
5318 bool pretenure = instr->hydrogen()->pretenure(); | 5318 bool pretenure = instr->hydrogen()->pretenure(); |
5319 if (!pretenure && instr->hydrogen()->has_no_literals()) { | 5319 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
5320 FastNewClosureStub stub(isolate(), | 5320 FastNewClosureStub stub(isolate(), |
5321 instr->hydrogen()->strict_mode(), | 5321 instr->hydrogen()->strict_mode(), |
5322 instr->hydrogen()->is_generator()); | 5322 instr->hydrogen()->is_generator()); |
5323 __ Move(rbx, instr->hydrogen()->shared_info()); | 5323 __ Move(rbx, instr->hydrogen()->shared_info()); |
5324 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5324 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
5325 } else { | 5325 } else { |
5326 __ Push(rsi); | 5326 __ Push(rsi); |
5327 __ Push(instr->hydrogen()->shared_info()); | 5327 __ Push(instr->hydrogen()->shared_info()); |
5328 __ PushRoot(pretenure ? Heap::kTrueValueRootIndex : | 5328 __ PushRoot(pretenure ? Heap::kTrueValueRootIndex : |
5329 Heap::kFalseValueRootIndex); | 5329 Heap::kFalseValueRootIndex); |
5330 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); | 5330 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); |
5331 } | 5331 } |
5332 } | 5332 } |
5333 | 5333 |
5334 | 5334 |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5727 __ bind(deferred->exit()); | 5727 __ bind(deferred->exit()); |
5728 __ bind(&done); | 5728 __ bind(&done); |
5729 } | 5729 } |
5730 | 5730 |
5731 | 5731 |
5732 #undef __ | 5732 #undef __ |
5733 | 5733 |
5734 } } // namespace v8::internal | 5734 } } // namespace v8::internal |
5735 | 5735 |
5736 #endif // V8_TARGET_ARCH_X64 | 5736 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |