| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 2011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2022 | 2022 |
| 2023 | 2023 |
| 2024 void CallFunctionStub::Generate(MacroAssembler* masm) { | 2024 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| 2025 CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod()); | 2025 CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod()); |
| 2026 } | 2026 } |
| 2027 | 2027 |
| 2028 | 2028 |
| 2029 void CallConstructStub::Generate(MacroAssembler* masm) { | 2029 void CallConstructStub::Generate(MacroAssembler* masm) { |
| 2030 // rax : number of arguments | 2030 // rax : number of arguments |
| 2031 // rbx : feedback vector | 2031 // rbx : feedback vector |
| 2032 // rdx : (only if rbx is not the megamorphic symbol) slot in feedback | 2032 // rcx : original constructor (for IsSuperConstructorCall) |
| 2033 // vector (Smi) | 2033 // rdx : slot in feedback vector (Smi, for RecordCallTarget) |
| 2034 // rdi : constructor function | 2034 // rdi : constructor function |
| 2035 Label slow, non_function_call; | 2035 Label slow, non_function_call; |
| 2036 | 2036 |
| 2037 // Check that function is not a smi. | 2037 // Check that function is not a smi. |
| 2038 __ JumpIfSmi(rdi, &non_function_call); | 2038 __ JumpIfSmi(rdi, &non_function_call); |
| 2039 // Check that function is a JSFunction. | 2039 // Check that function is a JSFunction. |
| 2040 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); | 2040 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, r11); |
| 2041 __ j(not_equal, &slow); | 2041 __ j(not_equal, &slow); |
| 2042 | 2042 |
| 2043 if (RecordCallTarget()) { | 2043 if (RecordCallTarget()) { |
| 2044 if (IsSuperConstructorCall()) { |
| 2045 __ Push(rcx); |
| 2046 } |
| 2044 GenerateRecordCallTarget(masm); | 2047 GenerateRecordCallTarget(masm); |
| 2048 if (IsSuperConstructorCall()) { |
| 2049 __ Pop(rcx); |
| 2050 } |
| 2045 | 2051 |
| 2046 __ SmiToInteger32(rdx, rdx); | 2052 __ SmiToInteger32(rdx, rdx); |
| 2047 if (FLAG_pretenuring_call_new) { | 2053 if (FLAG_pretenuring_call_new) { |
| 2048 // Put the AllocationSite from the feedback vector into ebx. | 2054 // Put the AllocationSite from the feedback vector into ebx. |
| 2049 // By adding kPointerSize we encode that we know the AllocationSite | 2055 // By adding kPointerSize we encode that we know the AllocationSite |
| 2050 // entry is at the feedback vector slot given by rdx + 1. | 2056 // entry is at the feedback vector slot given by rdx + 1. |
| 2051 __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size, | 2057 __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size, |
| 2052 FixedArray::kHeaderSize + kPointerSize)); | 2058 FixedArray::kHeaderSize + kPointerSize)); |
| 2053 } else { | 2059 } else { |
| 2054 Label feedback_register_initialized; | 2060 Label feedback_register_initialized; |
| 2055 // Put the AllocationSite from the feedback vector into rbx, or undefined. | 2061 // Put the AllocationSite from the feedback vector into rbx, or undefined. |
| 2056 __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size, | 2062 __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size, |
| 2057 FixedArray::kHeaderSize)); | 2063 FixedArray::kHeaderSize)); |
| 2058 __ CompareRoot(FieldOperand(rbx, 0), Heap::kAllocationSiteMapRootIndex); | 2064 __ CompareRoot(FieldOperand(rbx, 0), Heap::kAllocationSiteMapRootIndex); |
| 2059 __ j(equal, &feedback_register_initialized); | 2065 __ j(equal, &feedback_register_initialized); |
| 2060 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 2066 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
| 2061 __ bind(&feedback_register_initialized); | 2067 __ bind(&feedback_register_initialized); |
| 2062 } | 2068 } |
| 2063 | 2069 |
| 2064 __ AssertUndefinedOrAllocationSite(rbx); | 2070 __ AssertUndefinedOrAllocationSite(rbx); |
| 2065 } | 2071 } |
| 2066 | 2072 |
| 2067 // Pass original constructor to construct stub. | 2073 // Pass original constructor to construct stub. |
| 2068 if (IsSuperConstructorCall()) { | 2074 if (IsSuperConstructorCall()) { |
| 2069 __ movp(rdx, Operand(rsp, rax, times_pointer_size, 2 * kPointerSize)); | 2075 __ movp(rdx, rcx); |
| 2070 } else { | 2076 } else { |
| 2071 __ movp(rdx, rdi); | 2077 __ movp(rdx, rdi); |
| 2072 } | 2078 } |
| 2073 | 2079 |
| 2074 // Jump to the function-specific construct stub. | 2080 // Jump to the function-specific construct stub. |
| 2075 Register jmp_reg = rcx; | 2081 Register jmp_reg = rcx; |
| 2076 __ movp(jmp_reg, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 2082 __ movp(jmp_reg, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 2077 __ movp(jmp_reg, FieldOperand(jmp_reg, | 2083 __ movp(jmp_reg, FieldOperand(jmp_reg, |
| 2078 SharedFunctionInfo::kConstructStubOffset)); | 2084 SharedFunctionInfo::kConstructStubOffset)); |
| 2079 __ leap(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize)); | 2085 __ leap(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize)); |
| 2080 __ jmp(jmp_reg); | 2086 __ jmp(jmp_reg); |
| 2081 | 2087 |
| 2082 // rdi: called object | 2088 // rdi: called object |
| 2083 // rax: number of arguments | 2089 // rax: number of arguments |
| 2084 // rcx: object map | 2090 // r11: object map |
| 2085 Label do_call; | 2091 Label do_call; |
| 2086 __ bind(&slow); | 2092 __ bind(&slow); |
| 2087 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); | 2093 __ CmpInstanceType(r11, JS_FUNCTION_PROXY_TYPE); |
| 2088 __ j(not_equal, &non_function_call); | 2094 __ j(not_equal, &non_function_call); |
| 2089 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); | 2095 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); |
| 2090 __ jmp(&do_call); | 2096 __ jmp(&do_call); |
| 2091 | 2097 |
| 2092 __ bind(&non_function_call); | 2098 __ bind(&non_function_call); |
| 2093 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 2099 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
| 2094 __ bind(&do_call); | 2100 __ bind(&do_call); |
| 2095 // Set expected number of arguments to zero (not changing rax). | 2101 // Set expected number of arguments to zero (not changing rax). |
| 2096 __ Set(rbx, 0); | 2102 __ Set(rbx, 0); |
| 2097 __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 2103 __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| (...skipping 3325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5423 kStackSpace, nullptr, return_value_operand, NULL); | 5429 kStackSpace, nullptr, return_value_operand, NULL); |
| 5424 } | 5430 } |
| 5425 | 5431 |
| 5426 | 5432 |
| 5427 #undef __ | 5433 #undef __ |
| 5428 | 5434 |
| 5429 } // namespace internal | 5435 } // namespace internal |
| 5430 } // namespace v8 | 5436 } // namespace v8 |
| 5431 | 5437 |
| 5432 #endif // V8_TARGET_ARCH_X64 | 5438 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |