OLD | NEW |
1 | 1 |
2 // Copyright 2012 the V8 project authors. All rights reserved. | 2 // Copyright 2012 the V8 project authors. All rights reserved. |
3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
5 | 5 |
6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
7 | 7 |
8 #if V8_TARGET_ARCH_MIPS | 8 #if V8_TARGET_ARCH_MIPS |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 3967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3978 } | 3978 } |
3979 } | 3979 } |
3980 } | 3980 } |
3981 | 3981 |
3982 | 3982 |
3983 // ----------------------------------------------------------------------------- | 3983 // ----------------------------------------------------------------------------- |
3984 // JavaScript invokes. | 3984 // JavaScript invokes. |
3985 | 3985 |
3986 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 3986 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
3987 const ParameterCount& actual, | 3987 const ParameterCount& actual, |
3988 Handle<Code> code_constant, | |
3989 Register code_reg, | |
3990 Label* done, | 3988 Label* done, |
3991 bool* definitely_mismatches, | 3989 bool* definitely_mismatches, |
3992 InvokeFlag flag, | 3990 InvokeFlag flag, |
3993 const CallWrapper& call_wrapper) { | 3991 const CallWrapper& call_wrapper) { |
3994 bool definitely_matches = false; | 3992 bool definitely_matches = false; |
3995 *definitely_mismatches = false; | 3993 *definitely_mismatches = false; |
3996 Label regular_invoke; | 3994 Label regular_invoke; |
3997 | 3995 |
3998 // Check whether the expected and actual arguments count match. If not, | 3996 // Check whether the expected and actual arguments count match. If not, |
3999 // setup registers according to contract with ArgumentsAdaptorTrampoline: | 3997 // setup registers according to contract with ArgumentsAdaptorTrampoline: |
4000 // a0: actual arguments count | 3998 // a0: actual arguments count |
4001 // a1: function (passed through to callee) | 3999 // a1: function (passed through to callee) |
4002 // a2: expected arguments count | 4000 // a2: expected arguments count |
4003 | 4001 |
4004 // The code below is made a lot easier because the calling code already sets | 4002 // The code below is made a lot easier because the calling code already sets |
4005 // up actual and expected registers according to the contract if values are | 4003 // up actual and expected registers according to the contract if values are |
4006 // passed in registers. | 4004 // passed in registers. |
4007 DCHECK(actual.is_immediate() || actual.reg().is(a0)); | 4005 DCHECK(actual.is_immediate() || actual.reg().is(a0)); |
4008 DCHECK(expected.is_immediate() || expected.reg().is(a2)); | 4006 DCHECK(expected.is_immediate() || expected.reg().is(a2)); |
4009 DCHECK((!code_constant.is_null() && code_reg.is(no_reg)) || code_reg.is(a3)); | |
4010 | 4007 |
4011 if (expected.is_immediate()) { | 4008 if (expected.is_immediate()) { |
4012 DCHECK(actual.is_immediate()); | 4009 DCHECK(actual.is_immediate()); |
4013 li(a0, Operand(actual.immediate())); | 4010 li(a0, Operand(actual.immediate())); |
4014 if (expected.immediate() == actual.immediate()) { | 4011 if (expected.immediate() == actual.immediate()) { |
4015 definitely_matches = true; | 4012 definitely_matches = true; |
4016 } else { | 4013 } else { |
4017 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 4014 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
4018 if (expected.immediate() == sentinel) { | 4015 if (expected.immediate() == sentinel) { |
4019 // Don't worry about adapting arguments for builtins that | 4016 // Don't worry about adapting arguments for builtins that |
4020 // don't want that done. Skip adaption code by making it look | 4017 // don't want that done. Skip adaption code by making it look |
4021 // like we have a match between expected and actual number of | 4018 // like we have a match between expected and actual number of |
4022 // arguments. | 4019 // arguments. |
4023 definitely_matches = true; | 4020 definitely_matches = true; |
4024 } else { | 4021 } else { |
4025 *definitely_mismatches = true; | 4022 *definitely_mismatches = true; |
4026 li(a2, Operand(expected.immediate())); | 4023 li(a2, Operand(expected.immediate())); |
4027 } | 4024 } |
4028 } | 4025 } |
4029 } else if (actual.is_immediate()) { | 4026 } else if (actual.is_immediate()) { |
4030 li(a0, Operand(actual.immediate())); | 4027 li(a0, Operand(actual.immediate())); |
4031 Branch(®ular_invoke, eq, expected.reg(), Operand(a0)); | 4028 Branch(®ular_invoke, eq, expected.reg(), Operand(a0)); |
4032 } else { | 4029 } else { |
4033 Branch(®ular_invoke, eq, expected.reg(), Operand(actual.reg())); | 4030 Branch(®ular_invoke, eq, expected.reg(), Operand(actual.reg())); |
4034 } | 4031 } |
4035 | 4032 |
4036 if (!definitely_matches) { | 4033 if (!definitely_matches) { |
4037 if (!code_constant.is_null()) { | |
4038 li(a3, Operand(code_constant)); | |
4039 addiu(a3, a3, Code::kHeaderSize - kHeapObjectTag); | |
4040 } | |
4041 | |
4042 Handle<Code> adaptor = | 4034 Handle<Code> adaptor = |
4043 isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 4035 isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
4044 if (flag == CALL_FUNCTION) { | 4036 if (flag == CALL_FUNCTION) { |
4045 call_wrapper.BeforeCall(CallSize(adaptor)); | 4037 call_wrapper.BeforeCall(CallSize(adaptor)); |
4046 Call(adaptor); | 4038 Call(adaptor); |
4047 call_wrapper.AfterCall(); | 4039 call_wrapper.AfterCall(); |
4048 if (!*definitely_mismatches) { | 4040 if (!*definitely_mismatches) { |
4049 Branch(done); | 4041 Branch(done); |
4050 } | 4042 } |
4051 } else { | 4043 } else { |
4052 Jump(adaptor, RelocInfo::CODE_TARGET); | 4044 Jump(adaptor, RelocInfo::CODE_TARGET); |
4053 } | 4045 } |
4054 bind(®ular_invoke); | 4046 bind(®ular_invoke); |
4055 } | 4047 } |
4056 } | 4048 } |
4057 | 4049 |
4058 | 4050 |
4059 void MacroAssembler::InvokeCode(Register code, | 4051 void MacroAssembler::InvokeCode(Register code, |
4060 const ParameterCount& expected, | 4052 const ParameterCount& expected, |
4061 const ParameterCount& actual, | 4053 const ParameterCount& actual, |
4062 InvokeFlag flag, | 4054 InvokeFlag flag, |
4063 const CallWrapper& call_wrapper) { | 4055 const CallWrapper& call_wrapper) { |
4064 // You can't call a function without a valid frame. | 4056 // You can't call a function without a valid frame. |
4065 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 4057 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
4066 | 4058 |
4067 Label done; | 4059 Label done; |
4068 | 4060 |
4069 bool definitely_mismatches = false; | 4061 bool definitely_mismatches = false; |
4070 InvokePrologue(expected, actual, Handle<Code>::null(), code, | 4062 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, |
4071 &done, &definitely_mismatches, flag, | |
4072 call_wrapper); | 4063 call_wrapper); |
4073 if (!definitely_mismatches) { | 4064 if (!definitely_mismatches) { |
4074 if (flag == CALL_FUNCTION) { | 4065 if (flag == CALL_FUNCTION) { |
4075 call_wrapper.BeforeCall(CallSize(code)); | 4066 call_wrapper.BeforeCall(CallSize(code)); |
4076 Call(code); | 4067 Call(code); |
4077 call_wrapper.AfterCall(); | 4068 call_wrapper.AfterCall(); |
4078 } else { | 4069 } else { |
4079 DCHECK(flag == JUMP_FUNCTION); | 4070 DCHECK(flag == JUMP_FUNCTION); |
4080 Jump(code); | 4071 Jump(code); |
4081 } | 4072 } |
(...skipping 1775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5857 if (mag.shift > 0) sra(result, result, mag.shift); | 5848 if (mag.shift > 0) sra(result, result, mag.shift); |
5858 srl(at, dividend, 31); | 5849 srl(at, dividend, 31); |
5859 Addu(result, result, Operand(at)); | 5850 Addu(result, result, Operand(at)); |
5860 } | 5851 } |
5861 | 5852 |
5862 | 5853 |
5863 } // namespace internal | 5854 } // namespace internal |
5864 } // namespace v8 | 5855 } // namespace v8 |
5865 | 5856 |
5866 #endif // V8_TARGET_ARCH_MIPS | 5857 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |