| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 1857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1868 Register scratch, | 1868 Register scratch, |
| 1869 Label* failure) { | 1869 Label* failure) { |
| 1870 int kFlatAsciiStringMask = | 1870 int kFlatAsciiStringMask = |
| 1871 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | 1871 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; |
| 1872 int kFlatAsciiStringTag = ASCII_STRING_TYPE; | 1872 int kFlatAsciiStringTag = ASCII_STRING_TYPE; |
| 1873 and_(scratch, type, Operand(kFlatAsciiStringMask)); | 1873 and_(scratch, type, Operand(kFlatAsciiStringMask)); |
| 1874 cmp(scratch, Operand(kFlatAsciiStringTag)); | 1874 cmp(scratch, Operand(kFlatAsciiStringTag)); |
| 1875 b(ne, failure); | 1875 b(ne, failure); |
| 1876 } | 1876 } |
| 1877 | 1877 |
| 1878 static const int kRegisterPassedArguments = 4; |
| 1878 | 1879 |
| 1879 void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) { | 1880 void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) { |
| 1880 int frame_alignment = ActivationFrameAlignment(); | 1881 int frame_alignment = ActivationFrameAlignment(); |
| 1882 |
| 1883 // Reserve space for Isolate address which is always passed as last parameter |
| 1884 num_arguments += 1; |
| 1885 |
| 1881 // Up to four simple arguments are passed in registers r0..r3. | 1886 // Up to four simple arguments are passed in registers r0..r3. |
| 1882 int stack_passed_arguments = (num_arguments <= 4) ? 0 : num_arguments - 4; | 1887 int stack_passed_arguments = (num_arguments <= kRegisterPassedArguments) ? |
| 1888 0 : num_arguments - kRegisterPassedArguments; |
| 1883 if (frame_alignment > kPointerSize) { | 1889 if (frame_alignment > kPointerSize) { |
| 1884 // Make stack end at alignment and make room for num_arguments - 4 words | 1890 // Make stack end at alignment and make room for num_arguments - 4 words |
| 1885 // and the original value of sp. | 1891 // and the original value of sp. |
| 1886 mov(scratch, sp); | 1892 mov(scratch, sp); |
| 1887 sub(sp, sp, Operand((stack_passed_arguments + 1) * kPointerSize)); | 1893 sub(sp, sp, Operand((stack_passed_arguments + 1) * kPointerSize)); |
| 1888 ASSERT(IsPowerOf2(frame_alignment)); | 1894 ASSERT(IsPowerOf2(frame_alignment)); |
| 1889 and_(sp, sp, Operand(-frame_alignment)); | 1895 and_(sp, sp, Operand(-frame_alignment)); |
| 1890 str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize)); | 1896 str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize)); |
| 1891 } else { | 1897 } else { |
| 1892 sub(sp, sp, Operand(stack_passed_arguments * kPointerSize)); | 1898 sub(sp, sp, Operand(stack_passed_arguments * kPointerSize)); |
| 1893 } | 1899 } |
| 1894 } | 1900 } |
| 1895 | 1901 |
| 1896 | 1902 |
| 1897 void MacroAssembler::CallCFunction(ExternalReference function, | 1903 void MacroAssembler::CallCFunction(ExternalReference function, |
| 1898 int num_arguments) { | 1904 int num_arguments) { |
| 1899 mov(ip, Operand(function)); | 1905 CallCFunctionHelper(no_reg, function, ip, num_arguments); |
| 1900 CallCFunction(ip, num_arguments); | 1906 } |
| 1907 |
| 1908 void MacroAssembler::CallCFunction(Register function, |
| 1909 Register scratch, |
| 1910 int num_arguments) { |
| 1911 CallCFunctionHelper(function, |
| 1912 ExternalReference::the_hole_value_location(), |
| 1913 scratch, |
| 1914 num_arguments); |
| 1915 |
| 1901 } | 1916 } |
| 1902 | 1917 |
| 1903 | 1918 |
| 1904 void MacroAssembler::CallCFunction(Register function, int num_arguments) { | 1919 void MacroAssembler::CallCFunctionHelper(Register function, |
| 1920 ExternalReference function_reference, |
| 1921 Register scratch, |
| 1922 int num_arguments) { |
| 1923 // Push Isolate address as the last argument. |
| 1924 if (num_arguments < kRegisterPassedArguments) { |
| 1925 Register arg_to_reg[] = {r0, r1, r2, r3}; |
| 1926 Register r = arg_to_reg[num_arguments]; |
| 1927 mov(r, Operand(ExternalReference::isolate_address())); |
| 1928 } else { |
| 1929 int stack_passed_arguments = num_arguments - kRegisterPassedArguments; |
| 1930 // Push Isolate address on the stack after the arguments. |
| 1931 mov(scratch, Operand(ExternalReference::isolate_address())); |
| 1932 str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize)); |
| 1933 } |
| 1934 num_arguments += 1; |
| 1935 |
| 1905 // Make sure that the stack is aligned before calling a C function unless | 1936 // Make sure that the stack is aligned before calling a C function unless |
| 1906 // running in the simulator. The simulator has its own alignment check which | 1937 // running in the simulator. The simulator has its own alignment check which |
| 1907 // provides more information. | 1938 // provides more information. |
| 1908 #if defined(V8_HOST_ARCH_ARM) | 1939 #if defined(V8_HOST_ARCH_ARM) |
| 1909 if (FLAG_debug_code) { | 1940 if (FLAG_debug_code) { |
| 1910 int frame_alignment = OS::ActivationFrameAlignment(); | 1941 int frame_alignment = OS::ActivationFrameAlignment(); |
| 1911 int frame_alignment_mask = frame_alignment - 1; | 1942 int frame_alignment_mask = frame_alignment - 1; |
| 1912 if (frame_alignment > kPointerSize) { | 1943 if (frame_alignment > kPointerSize) { |
| 1913 ASSERT(IsPowerOf2(frame_alignment)); | 1944 ASSERT(IsPowerOf2(frame_alignment)); |
| 1914 Label alignment_as_expected; | 1945 Label alignment_as_expected; |
| 1915 tst(sp, Operand(frame_alignment_mask)); | 1946 tst(sp, Operand(frame_alignment_mask)); |
| 1916 b(eq, &alignment_as_expected); | 1947 b(eq, &alignment_as_expected); |
| 1917 // Don't use Check here, as it will call Runtime_Abort possibly | 1948 // Don't use Check here, as it will call Runtime_Abort possibly |
| 1918 // re-entering here. | 1949 // re-entering here. |
| 1919 stop("Unexpected alignment"); | 1950 stop("Unexpected alignment"); |
| 1920 bind(&alignment_as_expected); | 1951 bind(&alignment_as_expected); |
| 1921 } | 1952 } |
| 1922 } | 1953 } |
| 1923 #endif | 1954 #endif |
| 1924 | 1955 |
| 1925 // Just call directly. The function called cannot cause a GC, or | 1956 // Just call directly. The function called cannot cause a GC, or |
| 1926 // allow preemption, so the return address in the link register | 1957 // allow preemption, so the return address in the link register |
| 1927 // stays correct. | 1958 // stays correct. |
| 1959 if (function.is(no_reg)) { |
| 1960 mov(scratch, Operand(function_reference)); |
| 1961 function = scratch; |
| 1962 } |
| 1928 Call(function); | 1963 Call(function); |
| 1929 int stack_passed_arguments = (num_arguments <= 4) ? 0 : num_arguments - 4; | 1964 int stack_passed_arguments = (num_arguments <= kRegisterPassedArguments) ? |
| 1965 0 : num_arguments - kRegisterPassedArguments; |
| 1930 if (OS::ActivationFrameAlignment() > kPointerSize) { | 1966 if (OS::ActivationFrameAlignment() > kPointerSize) { |
| 1931 ldr(sp, MemOperand(sp, stack_passed_arguments * kPointerSize)); | 1967 ldr(sp, MemOperand(sp, stack_passed_arguments * kPointerSize)); |
| 1932 } else { | 1968 } else { |
| 1933 add(sp, sp, Operand(stack_passed_arguments * sizeof(kPointerSize))); | 1969 add(sp, sp, Operand(stack_passed_arguments * sizeof(kPointerSize))); |
| 1934 } | 1970 } |
| 1935 } | 1971 } |
| 1936 | 1972 |
| 1937 | 1973 |
| 1938 #ifdef ENABLE_DEBUGGER_SUPPORT | 1974 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 1939 CodePatcher::CodePatcher(byte* address, int instructions) | 1975 CodePatcher::CodePatcher(byte* address, int instructions) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1965 | 2001 |
| 1966 void CodePatcher::Emit(Address addr) { | 2002 void CodePatcher::Emit(Address addr) { |
| 1967 masm()->emit(reinterpret_cast<Instr>(addr)); | 2003 masm()->emit(reinterpret_cast<Instr>(addr)); |
| 1968 } | 2004 } |
| 1969 #endif // ENABLE_DEBUGGER_SUPPORT | 2005 #endif // ENABLE_DEBUGGER_SUPPORT |
| 1970 | 2006 |
| 1971 | 2007 |
| 1972 } } // namespace v8::internal | 2008 } } // namespace v8::internal |
| 1973 | 2009 |
| 1974 #endif // V8_TARGET_ARCH_ARM | 2010 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |