| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1926 xor_(dst, dst); | 1926 xor_(dst, dst); |
| 1927 } | 1927 } |
| 1928 } | 1928 } |
| 1929 | 1929 |
| 1930 | 1930 |
| 1931 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 1931 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
| 1932 const ParameterCount& actual, | 1932 const ParameterCount& actual, |
| 1933 Handle<Code> code_constant, | 1933 Handle<Code> code_constant, |
| 1934 const Operand& code_operand, | 1934 const Operand& code_operand, |
| 1935 Label* done, | 1935 Label* done, |
| 1936 bool* definitely_mismatches, |
| 1936 InvokeFlag flag, | 1937 InvokeFlag flag, |
| 1937 Label::Distance done_near, | 1938 Label::Distance done_near, |
| 1938 const CallWrapper& call_wrapper, | 1939 const CallWrapper& call_wrapper, |
| 1939 CallKind call_kind) { | 1940 CallKind call_kind) { |
| 1940 bool definitely_matches = false; | 1941 bool definitely_matches = false; |
| 1942 *definitely_mismatches = false; |
| 1941 Label invoke; | 1943 Label invoke; |
| 1942 if (expected.is_immediate()) { | 1944 if (expected.is_immediate()) { |
| 1943 ASSERT(actual.is_immediate()); | 1945 ASSERT(actual.is_immediate()); |
| 1944 if (expected.immediate() == actual.immediate()) { | 1946 if (expected.immediate() == actual.immediate()) { |
| 1945 definitely_matches = true; | 1947 definitely_matches = true; |
| 1946 } else { | 1948 } else { |
| 1947 mov(eax, actual.immediate()); | 1949 mov(eax, actual.immediate()); |
| 1948 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 1950 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
| 1949 if (expected.immediate() == sentinel) { | 1951 if (expected.immediate() == sentinel) { |
| 1950 // Don't worry about adapting arguments for builtins that | 1952 // Don't worry about adapting arguments for builtins that |
| 1951 // don't want that done. Skip adaption code by making it look | 1953 // don't want that done. Skip adaption code by making it look |
| 1952 // like we have a match between expected and actual number of | 1954 // like we have a match between expected and actual number of |
| 1953 // arguments. | 1955 // arguments. |
| 1954 definitely_matches = true; | 1956 definitely_matches = true; |
| 1955 } else { | 1957 } else { |
| 1958 *definitely_mismatches = true; |
| 1956 mov(ebx, expected.immediate()); | 1959 mov(ebx, expected.immediate()); |
| 1957 } | 1960 } |
| 1958 } | 1961 } |
| 1959 } else { | 1962 } else { |
| 1960 if (actual.is_immediate()) { | 1963 if (actual.is_immediate()) { |
| 1961 // Expected is in register, actual is immediate. This is the | 1964 // Expected is in register, actual is immediate. This is the |
| 1962 // case when we invoke function values without going through the | 1965 // case when we invoke function values without going through the |
| 1963 // IC mechanism. | 1966 // IC mechanism. |
| 1964 cmp(expected.reg(), actual.immediate()); | 1967 cmp(expected.reg(), actual.immediate()); |
| 1965 j(equal, &invoke); | 1968 j(equal, &invoke); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1983 add(edx, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 1986 add(edx, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 1984 } else if (!code_operand.is_reg(edx)) { | 1987 } else if (!code_operand.is_reg(edx)) { |
| 1985 mov(edx, code_operand); | 1988 mov(edx, code_operand); |
| 1986 } | 1989 } |
| 1987 | 1990 |
| 1988 if (flag == CALL_FUNCTION) { | 1991 if (flag == CALL_FUNCTION) { |
| 1989 call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET)); | 1992 call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET)); |
| 1990 SetCallKind(ecx, call_kind); | 1993 SetCallKind(ecx, call_kind); |
| 1991 call(adaptor, RelocInfo::CODE_TARGET); | 1994 call(adaptor, RelocInfo::CODE_TARGET); |
| 1992 call_wrapper.AfterCall(); | 1995 call_wrapper.AfterCall(); |
| 1993 jmp(done, done_near); | 1996 if (!*definitely_mismatches) { |
| 1997 jmp(done, done_near); |
| 1998 } |
| 1994 } else { | 1999 } else { |
| 1995 SetCallKind(ecx, call_kind); | 2000 SetCallKind(ecx, call_kind); |
| 1996 jmp(adaptor, RelocInfo::CODE_TARGET); | 2001 jmp(adaptor, RelocInfo::CODE_TARGET); |
| 1997 } | 2002 } |
| 1998 bind(&invoke); | 2003 bind(&invoke); |
| 1999 } | 2004 } |
| 2000 } | 2005 } |
| 2001 | 2006 |
| 2002 | 2007 |
| 2003 void MacroAssembler::InvokeCode(const Operand& code, | 2008 void MacroAssembler::InvokeCode(const Operand& code, |
| 2004 const ParameterCount& expected, | 2009 const ParameterCount& expected, |
| 2005 const ParameterCount& actual, | 2010 const ParameterCount& actual, |
| 2006 InvokeFlag flag, | 2011 InvokeFlag flag, |
| 2007 const CallWrapper& call_wrapper, | 2012 const CallWrapper& call_wrapper, |
| 2008 CallKind call_kind) { | 2013 CallKind call_kind) { |
| 2009 // You can't call a function without a valid frame. | 2014 // You can't call a function without a valid frame. |
| 2010 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 2015 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 2011 | 2016 |
| 2012 Label done; | 2017 Label done; |
| 2018 bool definitely_mismatches = false; |
| 2013 InvokePrologue(expected, actual, Handle<Code>::null(), code, | 2019 InvokePrologue(expected, actual, Handle<Code>::null(), code, |
| 2014 &done, flag, Label::kNear, call_wrapper, | 2020 &done, &definitely_mismatches, flag, Label::kNear, |
| 2015 call_kind); | 2021 call_wrapper, call_kind); |
| 2016 if (flag == CALL_FUNCTION) { | 2022 if (!definitely_mismatches) { |
| 2017 call_wrapper.BeforeCall(CallSize(code)); | 2023 if (flag == CALL_FUNCTION) { |
| 2018 SetCallKind(ecx, call_kind); | 2024 call_wrapper.BeforeCall(CallSize(code)); |
| 2019 call(code); | 2025 SetCallKind(ecx, call_kind); |
| 2020 call_wrapper.AfterCall(); | 2026 call(code); |
| 2021 } else { | 2027 call_wrapper.AfterCall(); |
| 2022 ASSERT(flag == JUMP_FUNCTION); | 2028 } else { |
| 2023 SetCallKind(ecx, call_kind); | 2029 ASSERT(flag == JUMP_FUNCTION); |
| 2024 jmp(code); | 2030 SetCallKind(ecx, call_kind); |
| 2031 jmp(code); |
| 2032 } |
| 2033 bind(&done); |
| 2025 } | 2034 } |
| 2026 bind(&done); | |
| 2027 } | 2035 } |
| 2028 | 2036 |
| 2029 | 2037 |
| 2030 void MacroAssembler::InvokeCode(Handle<Code> code, | 2038 void MacroAssembler::InvokeCode(Handle<Code> code, |
| 2031 const ParameterCount& expected, | 2039 const ParameterCount& expected, |
| 2032 const ParameterCount& actual, | 2040 const ParameterCount& actual, |
| 2033 RelocInfo::Mode rmode, | 2041 RelocInfo::Mode rmode, |
| 2034 InvokeFlag flag, | 2042 InvokeFlag flag, |
| 2035 const CallWrapper& call_wrapper, | 2043 const CallWrapper& call_wrapper, |
| 2036 CallKind call_kind) { | 2044 CallKind call_kind) { |
| 2037 // You can't call a function without a valid frame. | 2045 // You can't call a function without a valid frame. |
| 2038 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 2046 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 2039 | 2047 |
| 2040 Label done; | 2048 Label done; |
| 2041 Operand dummy(eax, 0); | 2049 Operand dummy(eax, 0); |
| 2042 InvokePrologue(expected, actual, code, dummy, &done, flag, Label::kNear, | 2050 bool definitely_mismatches = false; |
| 2043 call_wrapper, call_kind); | 2051 InvokePrologue(expected, actual, code, dummy, &done, &definitely_mismatches, |
| 2044 if (flag == CALL_FUNCTION) { | 2052 flag, Label::kNear, call_wrapper, call_kind); |
| 2045 call_wrapper.BeforeCall(CallSize(code, rmode)); | 2053 if (!definitely_mismatches) { |
| 2046 SetCallKind(ecx, call_kind); | 2054 if (flag == CALL_FUNCTION) { |
| 2047 call(code, rmode); | 2055 call_wrapper.BeforeCall(CallSize(code, rmode)); |
| 2048 call_wrapper.AfterCall(); | 2056 SetCallKind(ecx, call_kind); |
| 2049 } else { | 2057 call(code, rmode); |
| 2050 ASSERT(flag == JUMP_FUNCTION); | 2058 call_wrapper.AfterCall(); |
| 2051 SetCallKind(ecx, call_kind); | 2059 } else { |
| 2052 jmp(code, rmode); | 2060 ASSERT(flag == JUMP_FUNCTION); |
| 2061 SetCallKind(ecx, call_kind); |
| 2062 jmp(code, rmode); |
| 2063 } |
| 2064 bind(&done); |
| 2053 } | 2065 } |
| 2054 bind(&done); | |
| 2055 } | 2066 } |
| 2056 | 2067 |
| 2057 | 2068 |
| 2058 void MacroAssembler::InvokeFunction(Register fun, | 2069 void MacroAssembler::InvokeFunction(Register fun, |
| 2059 const ParameterCount& actual, | 2070 const ParameterCount& actual, |
| 2060 InvokeFlag flag, | 2071 InvokeFlag flag, |
| 2061 const CallWrapper& call_wrapper, | 2072 const CallWrapper& call_wrapper, |
| 2062 CallKind call_kind) { | 2073 CallKind call_kind) { |
| 2063 // You can't call a function without a valid frame. | 2074 // You can't call a function without a valid frame. |
| 2064 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 2075 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| (...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2739 cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset)); | 2750 cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset)); |
| 2740 Check(less_equal, "Live Bytes Count overflow chunk size"); | 2751 Check(less_equal, "Live Bytes Count overflow chunk size"); |
| 2741 } | 2752 } |
| 2742 | 2753 |
| 2743 bind(&done); | 2754 bind(&done); |
| 2744 } | 2755 } |
| 2745 | 2756 |
| 2746 } } // namespace v8::internal | 2757 } } // namespace v8::internal |
| 2747 | 2758 |
| 2748 #endif // V8_TARGET_ARCH_IA32 | 2759 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |