| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 | 
| 6 | 6 | 
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" | 
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" | 
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" | 
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" | 
| (...skipping 1840 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1851   // method. | 1851   // method. | 
| 1852   __ bind(&non_constructor); | 1852   __ bind(&non_constructor); | 
| 1853   { | 1853   { | 
| 1854     FrameScope scope(masm, StackFrame::INTERNAL); | 1854     FrameScope scope(masm, StackFrame::INTERNAL); | 
| 1855     __ Push(rdi); | 1855     __ Push(rdi); | 
| 1856     __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1856     __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 
| 1857   } | 1857   } | 
| 1858 } | 1858 } | 
| 1859 | 1859 | 
| 1860 | 1860 | 
|  | 1861 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, | 
|  | 1862                                     Register function_template_info, | 
|  | 1863                                     Register scratch0, Register scratch1, | 
|  | 1864                                     Register scratch2, | 
|  | 1865                                     Label* receiver_check_failed) { | 
|  | 1866   Register signature = scratch0; | 
|  | 1867   Register map = scratch1; | 
|  | 1868   Register constructor = scratch2; | 
|  | 1869 | 
|  | 1870   // If the receiver is not an object, jump to receiver_check_failed. | 
|  | 1871   __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, kScratchRegister); | 
|  | 1872   __ j(below, receiver_check_failed); | 
|  | 1873 | 
|  | 1874   // If there is no signature, return the holder. | 
|  | 1875   __ movp(signature, FieldOperand(function_template_info, | 
|  | 1876                                   FunctionTemplateInfo::kSignatureOffset)); | 
|  | 1877   __ CompareRoot(signature, Heap::kUndefinedValueRootIndex); | 
|  | 1878   Label receiver_check_passed; | 
|  | 1879   __ j(equal, &receiver_check_passed, Label::kNear); | 
|  | 1880 | 
|  | 1881   // Walk the prototype chain. | 
|  | 1882   Label prototype_loop_start; | 
|  | 1883   __ bind(&prototype_loop_start); | 
|  | 1884 | 
|  | 1885   // End if the receiver is null or if it's a hidden prototype. | 
|  | 1886   __ CompareRoot(receiver, Heap::kNullValueRootIndex); | 
|  | 1887   __ j(equal, receiver_check_failed, Label::kNear); | 
|  | 1888   __ movp(map, FieldOperand(receiver, HeapObject::kMapOffset)); | 
|  | 1889   __ testq(FieldOperand(map, Map::kBitField3Offset), | 
|  | 1890            Immediate(Map::IsHiddenPrototype::kMask)); | 
|  | 1891   __ j(not_zero, receiver_check_failed, Label::kNear); | 
|  | 1892 | 
|  | 1893   // Get the constructor, if any. | 
|  | 1894   __ GetMapConstructor(constructor, map, kScratchRegister); | 
|  | 1895   __ CmpInstanceType(kScratchRegister, JS_FUNCTION_TYPE); | 
|  | 1896   Label next_prototype; | 
|  | 1897   __ j(not_equal, &next_prototype, Label::kNear); | 
|  | 1898 | 
|  | 1899   // Get the constructor's signature. | 
|  | 1900   Register type = constructor; | 
|  | 1901   __ movp(type, | 
|  | 1902           FieldOperand(constructor, JSFunction::kSharedFunctionInfoOffset)); | 
|  | 1903   __ movp(type, FieldOperand(type, SharedFunctionInfo::kFunctionDataOffset)); | 
|  | 1904 | 
|  | 1905   // Loop through the chain of inheriting function templates. | 
|  | 1906   Label function_template_loop; | 
|  | 1907   __ bind(&function_template_loop); | 
|  | 1908 | 
|  | 1909   // If the signatures match, we have a compatible receiver. | 
|  | 1910   __ cmpp(signature, type); | 
|  | 1911   __ j(equal, &receiver_check_passed, Label::kNear); | 
|  | 1912 | 
|  | 1913   // If the current type is not a FunctionTemplateInfo, load the next prototype | 
|  | 1914   // in the chain. | 
|  | 1915   __ JumpIfSmi(type, &next_prototype, Label::kNear); | 
|  | 1916   __ CmpObjectType(type, FUNCTION_TEMPLATE_INFO_TYPE, kScratchRegister); | 
|  | 1917   __ j(not_equal, &next_prototype, Label::kNear); | 
|  | 1918 | 
|  | 1919   // Otherwise load the parent function template and iterate. | 
|  | 1920   __ movp(type, | 
|  | 1921           FieldOperand(type, FunctionTemplateInfo::kParentTemplateOffset)); | 
|  | 1922   __ jmp(&function_template_loop, Label::kNear); | 
|  | 1923 | 
|  | 1924   // Load the next prototype and iterate. | 
|  | 1925   __ bind(&next_prototype); | 
|  | 1926   __ movp(receiver, FieldOperand(map, Map::kPrototypeOffset)); | 
|  | 1927   __ jmp(&prototype_loop_start, Label::kNear); | 
|  | 1928 | 
|  | 1929   __ bind(&receiver_check_passed); | 
|  | 1930 } | 
|  | 1931 | 
|  | 1932 | 
|  | 1933 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { | 
|  | 1934   // ----------- S t a t e ------------- | 
|  | 1935   //  -- rax                : number of arguments (not including the receiver) | 
|  | 1936   //  -- rdi                : callee | 
|  | 1937   //  -- rsi                : context | 
|  | 1938   //  -- rsp[0]             : return address | 
|  | 1939   //  -- rsp[8]             : last argument | 
|  | 1940   //  -- ... | 
|  | 1941   //  -- rsp[rax * 8]       : first argument | 
|  | 1942   //  -- rsp[(rax + 1) * 8] : receiver | 
|  | 1943   // ----------------------------------- | 
|  | 1944 | 
|  | 1945   StackArgumentsAccessor args(rsp, rax); | 
|  | 1946   __ movp(rcx, args.GetReceiverOperand()); | 
|  | 1947 | 
|  | 1948   // Update the receiver if this is a contextual call. | 
|  | 1949   Label set_global_proxy, valid_receiver; | 
|  | 1950   __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); | 
|  | 1951   __ j(equal, &set_global_proxy); | 
|  | 1952   __ bind(&valid_receiver); | 
|  | 1953 | 
|  | 1954   // Load the FunctionTemplateInfo. | 
|  | 1955   __ movp(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 
|  | 1956   __ movp(rbx, FieldOperand(rbx, SharedFunctionInfo::kFunctionDataOffset)); | 
|  | 1957 | 
|  | 1958   // Do the compatible receiver check. | 
|  | 1959   Label receiver_check_failed; | 
|  | 1960   CompatibleReceiverCheck(masm, rcx, rbx, rdx, r8, r9, &receiver_check_failed); | 
|  | 1961 | 
|  | 1962   // Get the callback offset from the FunctionTemplateInfo, and jump to the | 
|  | 1963   // beginning of the code. | 
|  | 1964   __ movp(rdx, FieldOperand(rbx, FunctionTemplateInfo::kCallCodeOffset)); | 
|  | 1965   __ movp(rdx, FieldOperand(rdx, CallHandlerInfo::kFastHandlerOffset)); | 
|  | 1966   __ addp(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 
|  | 1967   __ jmp(rdx); | 
|  | 1968 | 
|  | 1969   __ bind(&set_global_proxy); | 
|  | 1970   __ movp(rcx, GlobalObjectOperand()); | 
|  | 1971   __ movp(rcx, FieldOperand(rcx, JSGlobalObject::kGlobalProxyOffset)); | 
|  | 1972   __ movp(args.GetReceiverOperand(), rcx); | 
|  | 1973   __ jmp(&valid_receiver, Label::kNear); | 
|  | 1974 | 
|  | 1975   // Compatible receiver check failed: pop return address, arguments and | 
|  | 1976   // receiver and throw an Illegal Invocation exception. | 
|  | 1977   __ bind(&receiver_check_failed); | 
|  | 1978   __ PopReturnAddressTo(rbx); | 
|  | 1979   __ leap(rax, Operand(rax, times_pointer_size, 1 * kPointerSize)); | 
|  | 1980   __ addp(rsp, rax); | 
|  | 1981   __ PushReturnAddressFrom(rbx); | 
|  | 1982   { | 
|  | 1983     FrameScope scope(masm, StackFrame::INTERNAL); | 
|  | 1984     __ TailCallRuntime(Runtime::kThrowIllegalInvocation, 0, 1); | 
|  | 1985   } | 
|  | 1986 } | 
|  | 1987 | 
|  | 1988 | 
| 1861 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 1989 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 
| 1862   // Lookup the function in the JavaScript frame. | 1990   // Lookup the function in the JavaScript frame. | 
| 1863   __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1991   __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 
| 1864   { | 1992   { | 
| 1865     FrameScope scope(masm, StackFrame::INTERNAL); | 1993     FrameScope scope(masm, StackFrame::INTERNAL); | 
| 1866     // Pass function as argument. | 1994     // Pass function as argument. | 
| 1867     __ Push(rax); | 1995     __ Push(rax); | 
| 1868     __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); | 1996     __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); | 
| 1869   } | 1997   } | 
| 1870 | 1998 | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1910   __ ret(0); | 2038   __ ret(0); | 
| 1911 } | 2039 } | 
| 1912 | 2040 | 
| 1913 | 2041 | 
| 1914 #undef __ | 2042 #undef __ | 
| 1915 | 2043 | 
| 1916 }  // namespace internal | 2044 }  // namespace internal | 
| 1917 }  // namespace v8 | 2045 }  // namespace v8 | 
| 1918 | 2046 | 
| 1919 #endif  // V8_TARGET_ARCH_X64 | 2047 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|