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 |