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 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 const ExternalReference& ext, int result_size) { | 631 const ExternalReference& ext, int result_size) { |
632 // Set the entry point and jump to the C entry runtime stub. | 632 // Set the entry point and jump to the C entry runtime stub. |
633 movq(rbx, ext); | 633 movq(rbx, ext); |
634 CEntryStub ces(result_size); | 634 CEntryStub ces(result_size); |
635 return TryTailCallStub(&ces); | 635 return TryTailCallStub(&ces); |
636 } | 636 } |
637 | 637 |
638 | 638 |
639 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, | 639 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, |
640 InvokeFlag flag, | 640 InvokeFlag flag, |
641 PostCallGenerator* post_call_generator) { | 641 CallWrapper* call_wrapper) { |
642 // Calls are not allowed in some stubs. | 642 // Calls are not allowed in some stubs. |
643 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); | 643 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); |
644 | 644 |
645 // Rely on the assertion to check that the number of provided | 645 // Rely on the assertion to check that the number of provided |
646 // arguments match the expected number of arguments. Fake a | 646 // arguments match the expected number of arguments. Fake a |
647 // parameter count to avoid emitting code to do the check. | 647 // parameter count to avoid emitting code to do the check. |
648 ParameterCount expected(0); | 648 ParameterCount expected(0); |
649 GetBuiltinEntry(rdx, id); | 649 GetBuiltinEntry(rdx, id); |
650 InvokeCode(rdx, expected, expected, flag, post_call_generator); | 650 InvokeCode(rdx, expected, expected, flag, call_wrapper); |
651 } | 651 } |
652 | 652 |
653 | 653 |
654 void MacroAssembler::GetBuiltinFunction(Register target, | 654 void MacroAssembler::GetBuiltinFunction(Register target, |
655 Builtins::JavaScript id) { | 655 Builtins::JavaScript id) { |
656 // Load the builtins object into target register. | 656 // Load the builtins object into target register. |
657 movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 657 movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
658 movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); | 658 movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); |
659 movq(target, FieldOperand(target, | 659 movq(target, FieldOperand(target, |
660 JSBuiltinsObject::OffsetOfFunctionWithId(id))); | 660 JSBuiltinsObject::OffsetOfFunctionWithId(id))); |
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1417 } | 1417 } |
1418 | 1418 |
1419 | 1419 |
1420 void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { | 1420 void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { |
1421 // TODO(X64): Inline this | 1421 // TODO(X64): Inline this |
1422 jmp(code_object, rmode); | 1422 jmp(code_object, rmode); |
1423 } | 1423 } |
1424 | 1424 |
1425 | 1425 |
1426 void MacroAssembler::Call(ExternalReference ext) { | 1426 void MacroAssembler::Call(ExternalReference ext) { |
| 1427 #ifdef DEBUG |
| 1428 int pre_position = pc_offset(); |
| 1429 #endif |
1427 movq(kScratchRegister, ext); | 1430 movq(kScratchRegister, ext); |
1428 call(kScratchRegister); | 1431 call(kScratchRegister); |
| 1432 #ifdef DEBUG |
| 1433 int post_position = pc_offset(); |
| 1434 CHECK_EQ(pre_position + CallSize(ext), post_position); |
| 1435 #endif |
1429 } | 1436 } |
1430 | 1437 |
1431 | 1438 |
1432 void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { | 1439 void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { |
| 1440 #ifdef DEBUG |
| 1441 int pre_position = pc_offset(); |
| 1442 #endif |
1433 movq(kScratchRegister, destination, rmode); | 1443 movq(kScratchRegister, destination, rmode); |
1434 call(kScratchRegister); | 1444 call(kScratchRegister); |
| 1445 #ifdef DEBUG |
| 1446 int post_position = pc_offset(); |
| 1447 CHECK_EQ(pre_position + CallSize(destination, rmode), post_position); |
| 1448 #endif |
1435 } | 1449 } |
1436 | 1450 |
1437 | 1451 |
1438 void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) { | 1452 void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) { |
| 1453 #ifdef DEBUG |
| 1454 int pre_position = pc_offset(); |
| 1455 #endif |
1439 ASSERT(RelocInfo::IsCodeTarget(rmode)); | 1456 ASSERT(RelocInfo::IsCodeTarget(rmode)); |
1440 call(code_object, rmode); | 1457 call(code_object, rmode); |
| 1458 #ifdef DEBUG |
| 1459 int post_position = pc_offset(); |
| 1460 CHECK_EQ(pre_position + CallSize(code_object), post_position); |
| 1461 #endif |
1441 } | 1462 } |
1442 | 1463 |
1443 | 1464 |
1444 void MacroAssembler::Pushad() { | 1465 void MacroAssembler::Pushad() { |
1445 push(rax); | 1466 push(rax); |
1446 push(rcx); | 1467 push(rcx); |
1447 push(rdx); | 1468 push(rdx); |
1448 push(rbx); | 1469 push(rbx); |
1449 // Not pushing rsp or rbp. | 1470 // Not pushing rsp or rbp. |
1450 push(rsi); | 1471 push(rsi); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1861 CEntryStub ces(1); | 1882 CEntryStub ces(1); |
1862 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 1883 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
1863 } | 1884 } |
1864 #endif // ENABLE_DEBUGGER_SUPPORT | 1885 #endif // ENABLE_DEBUGGER_SUPPORT |
1865 | 1886 |
1866 | 1887 |
1867 void MacroAssembler::InvokeCode(Register code, | 1888 void MacroAssembler::InvokeCode(Register code, |
1868 const ParameterCount& expected, | 1889 const ParameterCount& expected, |
1869 const ParameterCount& actual, | 1890 const ParameterCount& actual, |
1870 InvokeFlag flag, | 1891 InvokeFlag flag, |
1871 PostCallGenerator* post_call_generator) { | 1892 CallWrapper* call_wrapper) { |
1872 NearLabel done; | 1893 NearLabel done; |
1873 InvokePrologue(expected, | 1894 InvokePrologue(expected, |
1874 actual, | 1895 actual, |
1875 Handle<Code>::null(), | 1896 Handle<Code>::null(), |
1876 code, | 1897 code, |
1877 &done, | 1898 &done, |
1878 flag, | 1899 flag, |
1879 post_call_generator); | 1900 call_wrapper); |
1880 if (flag == CALL_FUNCTION) { | 1901 if (flag == CALL_FUNCTION) { |
| 1902 if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code)); |
1881 call(code); | 1903 call(code); |
1882 if (post_call_generator != NULL) post_call_generator->Generate(); | 1904 if (call_wrapper != NULL) call_wrapper->AfterCall(); |
1883 } else { | 1905 } else { |
1884 ASSERT(flag == JUMP_FUNCTION); | 1906 ASSERT(flag == JUMP_FUNCTION); |
1885 jmp(code); | 1907 jmp(code); |
1886 } | 1908 } |
1887 bind(&done); | 1909 bind(&done); |
1888 } | 1910 } |
1889 | 1911 |
1890 | 1912 |
1891 void MacroAssembler::InvokeCode(Handle<Code> code, | 1913 void MacroAssembler::InvokeCode(Handle<Code> code, |
1892 const ParameterCount& expected, | 1914 const ParameterCount& expected, |
1893 const ParameterCount& actual, | 1915 const ParameterCount& actual, |
1894 RelocInfo::Mode rmode, | 1916 RelocInfo::Mode rmode, |
1895 InvokeFlag flag, | 1917 InvokeFlag flag, |
1896 PostCallGenerator* post_call_generator) { | 1918 CallWrapper* call_wrapper) { |
1897 NearLabel done; | 1919 NearLabel done; |
1898 Register dummy = rax; | 1920 Register dummy = rax; |
1899 InvokePrologue(expected, | 1921 InvokePrologue(expected, |
1900 actual, | 1922 actual, |
1901 code, | 1923 code, |
1902 dummy, | 1924 dummy, |
1903 &done, | 1925 &done, |
1904 flag, | 1926 flag, |
1905 post_call_generator); | 1927 call_wrapper); |
1906 if (flag == CALL_FUNCTION) { | 1928 if (flag == CALL_FUNCTION) { |
| 1929 if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code)); |
1907 Call(code, rmode); | 1930 Call(code, rmode); |
1908 if (post_call_generator != NULL) post_call_generator->Generate(); | 1931 if (call_wrapper != NULL) call_wrapper->AfterCall(); |
1909 } else { | 1932 } else { |
1910 ASSERT(flag == JUMP_FUNCTION); | 1933 ASSERT(flag == JUMP_FUNCTION); |
1911 Jump(code, rmode); | 1934 Jump(code, rmode); |
1912 } | 1935 } |
1913 bind(&done); | 1936 bind(&done); |
1914 } | 1937 } |
1915 | 1938 |
1916 | 1939 |
1917 void MacroAssembler::InvokeFunction(Register function, | 1940 void MacroAssembler::InvokeFunction(Register function, |
1918 const ParameterCount& actual, | 1941 const ParameterCount& actual, |
1919 InvokeFlag flag, | 1942 InvokeFlag flag, |
1920 PostCallGenerator* post_call_generator) { | 1943 CallWrapper* call_wrapper) { |
1921 ASSERT(function.is(rdi)); | 1944 ASSERT(function.is(rdi)); |
1922 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 1945 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
1923 movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); | 1946 movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); |
1924 movsxlq(rbx, | 1947 movsxlq(rbx, |
1925 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); | 1948 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); |
1926 // Advances rdx to the end of the Code object header, to the start of | 1949 // Advances rdx to the end of the Code object header, to the start of |
1927 // the executable code. | 1950 // the executable code. |
1928 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 1951 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
1929 | 1952 |
1930 ParameterCount expected(rbx); | 1953 ParameterCount expected(rbx); |
1931 InvokeCode(rdx, expected, actual, flag, post_call_generator); | 1954 InvokeCode(rdx, expected, actual, flag, call_wrapper); |
1932 } | 1955 } |
1933 | 1956 |
1934 | 1957 |
1935 void MacroAssembler::InvokeFunction(JSFunction* function, | 1958 void MacroAssembler::InvokeFunction(JSFunction* function, |
1936 const ParameterCount& actual, | 1959 const ParameterCount& actual, |
1937 InvokeFlag flag, | 1960 InvokeFlag flag, |
1938 PostCallGenerator* post_call_generator) { | 1961 CallWrapper* call_wrapper) { |
1939 ASSERT(function->is_compiled()); | 1962 ASSERT(function->is_compiled()); |
1940 // Get the function and setup the context. | 1963 // Get the function and setup the context. |
1941 Move(rdi, Handle<JSFunction>(function)); | 1964 Move(rdi, Handle<JSFunction>(function)); |
1942 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 1965 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
1943 | 1966 |
1944 if (V8::UseCrankshaft()) { | 1967 if (V8::UseCrankshaft()) { |
1945 // Since Crankshaft can recompile a function, we need to load | 1968 // Since Crankshaft can recompile a function, we need to load |
1946 // the Code object every time we call the function. | 1969 // the Code object every time we call the function. |
1947 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 1970 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
1948 ParameterCount expected(function->shared()->formal_parameter_count()); | 1971 ParameterCount expected(function->shared()->formal_parameter_count()); |
1949 InvokeCode(rdx, expected, actual, flag, post_call_generator); | 1972 InvokeCode(rdx, expected, actual, flag, call_wrapper); |
1950 } else { | 1973 } else { |
1951 // Invoke the cached code. | 1974 // Invoke the cached code. |
1952 Handle<Code> code(function->code()); | 1975 Handle<Code> code(function->code()); |
1953 ParameterCount expected(function->shared()->formal_parameter_count()); | 1976 ParameterCount expected(function->shared()->formal_parameter_count()); |
1954 InvokeCode(code, | 1977 InvokeCode(code, |
1955 expected, | 1978 expected, |
1956 actual, | 1979 actual, |
1957 RelocInfo::CODE_TARGET, | 1980 RelocInfo::CODE_TARGET, |
1958 flag, | 1981 flag, |
1959 post_call_generator); | 1982 call_wrapper); |
1960 } | 1983 } |
1961 } | 1984 } |
1962 | 1985 |
1963 | 1986 |
1964 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 1987 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
1965 push(rbp); | 1988 push(rbp); |
1966 movq(rbp, rsp); | 1989 movq(rbp, rsp); |
1967 push(rsi); // Context. | 1990 push(rsi); // Context. |
1968 Push(Smi::FromInt(type)); | 1991 Push(Smi::FromInt(type)); |
1969 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); | 1992 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2664 CPU::FlushICache(address_, size_); | 2687 CPU::FlushICache(address_, size_); |
2665 | 2688 |
2666 // Check that the code was patched as expected. | 2689 // Check that the code was patched as expected. |
2667 ASSERT(masm_.pc_ == address_ + size_); | 2690 ASSERT(masm_.pc_ == address_ + size_); |
2668 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2691 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
2669 } | 2692 } |
2670 | 2693 |
2671 } } // namespace v8::internal | 2694 } } // namespace v8::internal |
2672 | 2695 |
2673 #endif // V8_TARGET_ARCH_X64 | 2696 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |