| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 const ExternalReference& ext, int result_size) { | 637 const ExternalReference& ext, int result_size) { |
| 638 // Set the entry point and jump to the C entry runtime stub. | 638 // Set the entry point and jump to the C entry runtime stub. |
| 639 movq(rbx, ext); | 639 movq(rbx, ext); |
| 640 CEntryStub ces(result_size); | 640 CEntryStub ces(result_size); |
| 641 return TryTailCallStub(&ces); | 641 return TryTailCallStub(&ces); |
| 642 } | 642 } |
| 643 | 643 |
| 644 | 644 |
| 645 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, | 645 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, |
| 646 InvokeFlag flag, | 646 InvokeFlag flag, |
| 647 PostCallGenerator* post_call_generator) { | 647 CallWrapper* call_wrapper) { |
| 648 // Calls are not allowed in some stubs. | 648 // Calls are not allowed in some stubs. |
| 649 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); | 649 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); |
| 650 | 650 |
| 651 // Rely on the assertion to check that the number of provided | 651 // Rely on the assertion to check that the number of provided |
| 652 // arguments match the expected number of arguments. Fake a | 652 // arguments match the expected number of arguments. Fake a |
| 653 // parameter count to avoid emitting code to do the check. | 653 // parameter count to avoid emitting code to do the check. |
| 654 ParameterCount expected(0); | 654 ParameterCount expected(0); |
| 655 GetBuiltinEntry(rdx, id); | 655 GetBuiltinEntry(rdx, id); |
| 656 InvokeCode(rdx, expected, expected, flag, post_call_generator); | 656 InvokeCode(rdx, expected, expected, flag, call_wrapper); |
| 657 } | 657 } |
| 658 | 658 |
| 659 | 659 |
| 660 void MacroAssembler::GetBuiltinFunction(Register target, | 660 void MacroAssembler::GetBuiltinFunction(Register target, |
| 661 Builtins::JavaScript id) { | 661 Builtins::JavaScript id) { |
| 662 // Load the builtins object into target register. | 662 // Load the builtins object into target register. |
| 663 movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 663 movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
| 664 movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); | 664 movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); |
| 665 movq(target, FieldOperand(target, | 665 movq(target, FieldOperand(target, |
| 666 JSBuiltinsObject::OffsetOfFunctionWithId(id))); | 666 JSBuiltinsObject::OffsetOfFunctionWithId(id))); |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1423 } | 1423 } |
| 1424 | 1424 |
| 1425 | 1425 |
| 1426 void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { | 1426 void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { |
| 1427 // TODO(X64): Inline this | 1427 // TODO(X64): Inline this |
| 1428 jmp(code_object, rmode); | 1428 jmp(code_object, rmode); |
| 1429 } | 1429 } |
| 1430 | 1430 |
| 1431 | 1431 |
| 1432 void MacroAssembler::Call(ExternalReference ext) { | 1432 void MacroAssembler::Call(ExternalReference ext) { |
| 1433 #ifdef DEBUG |
| 1434 int pre_position = pc_offset(); |
| 1435 #endif |
| 1433 movq(kScratchRegister, ext); | 1436 movq(kScratchRegister, ext); |
| 1434 call(kScratchRegister); | 1437 call(kScratchRegister); |
| 1438 #ifdef DEBUG |
| 1439 int post_position = pc_offset(); |
| 1440 CHECK_EQ(pre_position + CallSize(ext), post_position); |
| 1441 #endif |
| 1435 } | 1442 } |
| 1436 | 1443 |
| 1437 | 1444 |
| 1438 void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { | 1445 void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { |
| 1446 #ifdef DEBUG |
| 1447 int pre_position = pc_offset(); |
| 1448 #endif |
| 1439 movq(kScratchRegister, destination, rmode); | 1449 movq(kScratchRegister, destination, rmode); |
| 1440 call(kScratchRegister); | 1450 call(kScratchRegister); |
| 1451 #ifdef DEBUG |
| 1452 int post_position = pc_offset(); |
| 1453 CHECK_EQ(pre_position + CallSize(destination, rmode), post_position); |
| 1454 #endif |
| 1441 } | 1455 } |
| 1442 | 1456 |
| 1443 | 1457 |
| 1444 void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) { | 1458 void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) { |
| 1459 #ifdef DEBUG |
| 1460 int pre_position = pc_offset(); |
| 1461 #endif |
| 1445 ASSERT(RelocInfo::IsCodeTarget(rmode)); | 1462 ASSERT(RelocInfo::IsCodeTarget(rmode)); |
| 1446 call(code_object, rmode); | 1463 call(code_object, rmode); |
| 1464 #ifdef DEBUG |
| 1465 int post_position = pc_offset(); |
| 1466 CHECK_EQ(pre_position + CallSize(code_object), post_position); |
| 1467 #endif |
| 1447 } | 1468 } |
| 1448 | 1469 |
| 1449 | 1470 |
| 1450 void MacroAssembler::Pushad() { | 1471 void MacroAssembler::Pushad() { |
| 1451 push(rax); | 1472 push(rax); |
| 1452 push(rcx); | 1473 push(rcx); |
| 1453 push(rdx); | 1474 push(rdx); |
| 1454 push(rbx); | 1475 push(rbx); |
| 1455 // Not pushing rsp or rbp. | 1476 // Not pushing rsp or rbp. |
| 1456 push(rsi); | 1477 push(rsi); |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1868 CEntryStub ces(1); | 1889 CEntryStub ces(1); |
| 1869 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 1890 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
| 1870 } | 1891 } |
| 1871 #endif // ENABLE_DEBUGGER_SUPPORT | 1892 #endif // ENABLE_DEBUGGER_SUPPORT |
| 1872 | 1893 |
| 1873 | 1894 |
| 1874 void MacroAssembler::InvokeCode(Register code, | 1895 void MacroAssembler::InvokeCode(Register code, |
| 1875 const ParameterCount& expected, | 1896 const ParameterCount& expected, |
| 1876 const ParameterCount& actual, | 1897 const ParameterCount& actual, |
| 1877 InvokeFlag flag, | 1898 InvokeFlag flag, |
| 1878 PostCallGenerator* post_call_generator) { | 1899 CallWrapper* call_wrapper) { |
| 1879 NearLabel done; | 1900 NearLabel done; |
| 1880 InvokePrologue(expected, | 1901 InvokePrologue(expected, |
| 1881 actual, | 1902 actual, |
| 1882 Handle<Code>::null(), | 1903 Handle<Code>::null(), |
| 1883 code, | 1904 code, |
| 1884 &done, | 1905 &done, |
| 1885 flag, | 1906 flag, |
| 1886 post_call_generator); | 1907 call_wrapper); |
| 1887 if (flag == CALL_FUNCTION) { | 1908 if (flag == CALL_FUNCTION) { |
| 1909 if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code)); |
| 1888 call(code); | 1910 call(code); |
| 1889 if (post_call_generator != NULL) post_call_generator->Generate(); | 1911 if (call_wrapper != NULL) call_wrapper->AfterCall(); |
| 1890 } else { | 1912 } else { |
| 1891 ASSERT(flag == JUMP_FUNCTION); | 1913 ASSERT(flag == JUMP_FUNCTION); |
| 1892 jmp(code); | 1914 jmp(code); |
| 1893 } | 1915 } |
| 1894 bind(&done); | 1916 bind(&done); |
| 1895 } | 1917 } |
| 1896 | 1918 |
| 1897 | 1919 |
| 1898 void MacroAssembler::InvokeCode(Handle<Code> code, | 1920 void MacroAssembler::InvokeCode(Handle<Code> code, |
| 1899 const ParameterCount& expected, | 1921 const ParameterCount& expected, |
| 1900 const ParameterCount& actual, | 1922 const ParameterCount& actual, |
| 1901 RelocInfo::Mode rmode, | 1923 RelocInfo::Mode rmode, |
| 1902 InvokeFlag flag, | 1924 InvokeFlag flag, |
| 1903 PostCallGenerator* post_call_generator) { | 1925 CallWrapper* call_wrapper) { |
| 1904 NearLabel done; | 1926 NearLabel done; |
| 1905 Register dummy = rax; | 1927 Register dummy = rax; |
| 1906 InvokePrologue(expected, | 1928 InvokePrologue(expected, |
| 1907 actual, | 1929 actual, |
| 1908 code, | 1930 code, |
| 1909 dummy, | 1931 dummy, |
| 1910 &done, | 1932 &done, |
| 1911 flag, | 1933 flag, |
| 1912 post_call_generator); | 1934 call_wrapper); |
| 1913 if (flag == CALL_FUNCTION) { | 1935 if (flag == CALL_FUNCTION) { |
| 1936 if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code)); |
| 1914 Call(code, rmode); | 1937 Call(code, rmode); |
| 1915 if (post_call_generator != NULL) post_call_generator->Generate(); | 1938 if (call_wrapper != NULL) call_wrapper->AfterCall(); |
| 1916 } else { | 1939 } else { |
| 1917 ASSERT(flag == JUMP_FUNCTION); | 1940 ASSERT(flag == JUMP_FUNCTION); |
| 1918 Jump(code, rmode); | 1941 Jump(code, rmode); |
| 1919 } | 1942 } |
| 1920 bind(&done); | 1943 bind(&done); |
| 1921 } | 1944 } |
| 1922 | 1945 |
| 1923 | 1946 |
| 1924 void MacroAssembler::InvokeFunction(Register function, | 1947 void MacroAssembler::InvokeFunction(Register function, |
| 1925 const ParameterCount& actual, | 1948 const ParameterCount& actual, |
| 1926 InvokeFlag flag, | 1949 InvokeFlag flag, |
| 1927 PostCallGenerator* post_call_generator) { | 1950 CallWrapper* call_wrapper) { |
| 1928 ASSERT(function.is(rdi)); | 1951 ASSERT(function.is(rdi)); |
| 1929 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 1952 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
| 1930 movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); | 1953 movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); |
| 1931 movsxlq(rbx, | 1954 movsxlq(rbx, |
| 1932 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); | 1955 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 1933 // Advances rdx to the end of the Code object header, to the start of | 1956 // Advances rdx to the end of the Code object header, to the start of |
| 1934 // the executable code. | 1957 // the executable code. |
| 1935 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 1958 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
| 1936 | 1959 |
| 1937 ParameterCount expected(rbx); | 1960 ParameterCount expected(rbx); |
| 1938 InvokeCode(rdx, expected, actual, flag, post_call_generator); | 1961 InvokeCode(rdx, expected, actual, flag, call_wrapper); |
| 1939 } | 1962 } |
| 1940 | 1963 |
| 1941 | 1964 |
| 1942 void MacroAssembler::InvokeFunction(JSFunction* function, | 1965 void MacroAssembler::InvokeFunction(JSFunction* function, |
| 1943 const ParameterCount& actual, | 1966 const ParameterCount& actual, |
| 1944 InvokeFlag flag, | 1967 InvokeFlag flag, |
| 1945 PostCallGenerator* post_call_generator) { | 1968 CallWrapper* call_wrapper) { |
| 1946 ASSERT(function->is_compiled()); | 1969 ASSERT(function->is_compiled()); |
| 1947 // Get the function and setup the context. | 1970 // Get the function and setup the context. |
| 1948 Move(rdi, Handle<JSFunction>(function)); | 1971 Move(rdi, Handle<JSFunction>(function)); |
| 1949 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 1972 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
| 1950 | 1973 |
| 1951 if (V8::UseCrankshaft()) { | 1974 if (V8::UseCrankshaft()) { |
| 1952 // Since Crankshaft can recompile a function, we need to load | 1975 // Since Crankshaft can recompile a function, we need to load |
| 1953 // the Code object every time we call the function. | 1976 // the Code object every time we call the function. |
| 1954 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 1977 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
| 1955 ParameterCount expected(function->shared()->formal_parameter_count()); | 1978 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 1956 InvokeCode(rdx, expected, actual, flag, post_call_generator); | 1979 InvokeCode(rdx, expected, actual, flag, call_wrapper); |
| 1957 } else { | 1980 } else { |
| 1958 // Invoke the cached code. | 1981 // Invoke the cached code. |
| 1959 Handle<Code> code(function->code()); | 1982 Handle<Code> code(function->code()); |
| 1960 ParameterCount expected(function->shared()->formal_parameter_count()); | 1983 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 1961 InvokeCode(code, | 1984 InvokeCode(code, |
| 1962 expected, | 1985 expected, |
| 1963 actual, | 1986 actual, |
| 1964 RelocInfo::CODE_TARGET, | 1987 RelocInfo::CODE_TARGET, |
| 1965 flag, | 1988 flag, |
| 1966 post_call_generator); | 1989 call_wrapper); |
| 1967 } | 1990 } |
| 1968 } | 1991 } |
| 1969 | 1992 |
| 1970 | 1993 |
| 1971 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 1994 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
| 1972 push(rbp); | 1995 push(rbp); |
| 1973 movq(rbp, rsp); | 1996 movq(rbp, rsp); |
| 1974 push(rsi); // Context. | 1997 push(rsi); // Context. |
| 1975 Push(Smi::FromInt(type)); | 1998 Push(Smi::FromInt(type)); |
| 1976 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); | 1999 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2005 push(rbp); | 2028 push(rbp); |
| 2006 movq(rbp, rsp); | 2029 movq(rbp, rsp); |
| 2007 | 2030 |
| 2008 // Reserve room for entry stack pointer and push the code object. | 2031 // Reserve room for entry stack pointer and push the code object. |
| 2009 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); | 2032 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); |
| 2010 push(Immediate(0)); // Saved entry sp, patched before call. | 2033 push(Immediate(0)); // Saved entry sp, patched before call. |
| 2011 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); | 2034 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); |
| 2012 push(kScratchRegister); // Accessed from EditFrame::code_slot. | 2035 push(kScratchRegister); // Accessed from EditFrame::code_slot. |
| 2013 | 2036 |
| 2014 // Save the frame pointer and the context in top. | 2037 // Save the frame pointer and the context in top. |
| 2015 ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address); | |
| 2016 ExternalReference context_address(Isolate::k_context_address); | |
| 2017 if (save_rax) { | 2038 if (save_rax) { |
| 2018 movq(r14, rax); // Backup rax before we use it. | 2039 movq(r14, rax); // Backup rax in callee-save register. |
| 2019 } | 2040 } |
| 2020 | 2041 |
| 2021 movq(rax, rbp); | 2042 movq(kScratchRegister, ExternalReference(Isolate::k_c_entry_fp_address)); |
| 2022 store_rax(c_entry_fp_address); | 2043 movq(Operand(kScratchRegister, 0), rbp); |
| 2023 movq(rax, rsi); | 2044 |
| 2024 store_rax(context_address); | 2045 movq(kScratchRegister, ExternalReference(Isolate::k_context_address)); |
| 2046 movq(Operand(kScratchRegister, 0), rsi); |
| 2025 } | 2047 } |
| 2026 | 2048 |
| 2027 | 2049 |
| 2028 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, | 2050 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, |
| 2029 bool save_doubles) { | 2051 bool save_doubles) { |
| 2030 #ifdef _WIN64 | 2052 #ifdef _WIN64 |
| 2031 const int kShadowSpace = 4; | 2053 const int kShadowSpace = 4; |
| 2032 arg_stack_space += kShadowSpace; | 2054 arg_stack_space += kShadowSpace; |
| 2033 #endif | 2055 #endif |
| 2034 // Optionally save all XMM registers. | 2056 // Optionally save all XMM registers. |
| (...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2700 CPU::FlushICache(address_, size_); | 2722 CPU::FlushICache(address_, size_); |
| 2701 | 2723 |
| 2702 // Check that the code was patched as expected. | 2724 // Check that the code was patched as expected. |
| 2703 ASSERT(masm_.pc_ == address_ + size_); | 2725 ASSERT(masm_.pc_ == address_ + size_); |
| 2704 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2726 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 2705 } | 2727 } |
| 2706 | 2728 |
| 2707 } } // namespace v8::internal | 2729 } } // namespace v8::internal |
| 2708 | 2730 |
| 2709 #endif // V8_TARGET_ARCH_X64 | 2731 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |