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 2126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2137 CallFunctionNoFeedback(masm, | 2137 CallFunctionNoFeedback(masm, |
2138 arg_count(), | 2138 arg_count(), |
2139 true, | 2139 true, |
2140 CallAsMethod()); | 2140 CallAsMethod()); |
2141 | 2141 |
2142 // Unreachable. | 2142 // Unreachable. |
2143 __ int3(); | 2143 __ int3(); |
2144 } | 2144 } |
2145 | 2145 |
2146 | 2146 |
2147 void CallIC_RoundStub::Generate(MacroAssembler* masm) { | |
2148 Register function = rdi; | |
2149 Register vector = rbx; | |
2150 Register slot = rdx; | |
2151 | |
2152 Register temp = rax; | |
2153 XMMRegister xmm_temp1 = xmm1; | |
2154 XMMRegister xmm_temp2 = xmm0; | |
2155 Label tail, miss; | |
2156 | |
2157 __ SmiToInteger64(slot, slot); | |
2158 | |
2159 // Ensure nobody has snuck in another function. | |
2160 __ BranchIfNotBuiltin(function, temp, kMathRound, &miss); | |
2161 | |
2162 if (arg_count() > 0) { | |
2163 __ movp(temp, Operand(rsp, arg_count() * kPointerSize)); | |
2164 Handle<Map> map = isolate()->factory()->heap_number_map(); | |
2165 __ CheckMap(temp, map, &tail, DO_SMI_CHECK); | |
2166 | |
2167 __ movsd(xmm_temp1, FieldOperand(temp, HeapNumber::kValueOffset)); | |
2168 | |
2169 // If the number is >0, it doesn't round to -0 | |
2170 __ xorps(xmm_temp2, xmm_temp2); | |
2171 __ ucomisd(xmm_temp1, xmm_temp2); | |
2172 __ j(above, &tail, Label::kNear); | |
2173 | |
2174 // If the number is <-.5, it doesn't round to -0 | |
2175 static int64_t minus_one_half = V8_INT64_C(0xBFE0000000000000); // -0.5 | |
2176 __ movq(temp, minus_one_half); | |
2177 __ movq(xmm_temp2, temp); | |
2178 __ ucomisd(xmm_temp1, xmm_temp2); | |
2179 __ j(below, &tail, Label::kNear); | |
2180 | |
2181 // +0 doesn't round to -0 | |
2182 __ movmskpd(temp, xmm_temp1); | |
2183 __ testl(temp, Immediate(1)); | |
2184 __ j(zero, &tail, Label::kNear); | |
2185 | |
2186 __ Move(FieldOperand(vector, slot, times_pointer_size, | |
2187 FixedArray::kHeaderSize + kPointerSize), | |
2188 Smi::FromInt(kHasReturnedMinusZeroSentinel)); | |
2189 } | |
2190 | |
2191 __ bind(&tail); | |
2192 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); | |
2193 | |
2194 // Unreachable. | |
2195 __ int3(); | |
2196 | |
2197 __ bind(&miss); | |
2198 GenerateMiss(masm); | |
2199 __ jmp(&tail); | |
2200 } | |
2201 | |
2202 | |
2203 void CallIC_FloorStub::Generate(MacroAssembler* masm) { | |
2204 Register function = rdi; | |
2205 Register vector = rbx; | |
2206 Register slot = rdx; | |
2207 | |
2208 Register temp1 = rax; | |
2209 Register temp2 = rsi; | |
2210 Label tail, miss; | |
2211 | |
2212 __ SmiToInteger64(slot, slot); | |
2213 | |
2214 // Ensure nobody has snuck in another function. | |
2215 __ BranchIfNotBuiltin(function, temp1, kMathFloor, &miss); | |
2216 | |
2217 if (arg_count() > 0) { | |
2218 __ movp(temp1, Operand(rsp, arg_count() * kPointerSize)); | |
2219 Handle<Map> map = isolate()->factory()->heap_number_map(); | |
2220 __ CheckMap(temp1, map, &tail, DO_SMI_CHECK); | |
2221 | |
2222 // Only -0 floors to -0. | |
2223 __ movq(temp1, FieldOperand(temp1, HeapNumber::kValueOffset)); | |
2224 static int64_t minus_zero = V8_INT64_C(0x8000000000000000); // -0.0 | |
2225 __ movq(temp2, minus_zero); | |
2226 __ cmpq(temp1, temp2); | |
2227 __ j(not_equal, &tail); | |
2228 | |
2229 __ Move(FieldOperand(vector, slot, times_pointer_size, | |
2230 FixedArray::kHeaderSize + kPointerSize), | |
2231 Smi::FromInt(kHasReturnedMinusZeroSentinel)); | |
2232 } | |
2233 | |
2234 __ bind(&tail); | |
2235 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); | |
2236 | |
2237 // Unreachable. | |
2238 __ int3(); | |
2239 | |
2240 __ bind(&miss); | |
2241 GenerateMiss(masm); | |
2242 __ jmp(&tail); | |
2243 } | |
2244 | |
2245 | |
2246 void CallIC_CeilStub::Generate(MacroAssembler* masm) { | |
2247 Register function = rdi; | |
2248 Register vector = rbx; | |
2249 Register slot = rdx; | |
2250 | |
2251 Register temp = rax; | |
2252 XMMRegister xmm_temp1 = xmm1; | |
2253 XMMRegister xmm_temp2 = xmm0; | |
2254 Label tail, miss; | |
2255 | |
2256 __ SmiToInteger64(slot, slot); | |
2257 | |
2258 // Ensure nobody has snuck in another function. | |
2259 __ BranchIfNotBuiltin(function, temp, kMathCeil, &miss); | |
2260 | |
2261 if (arg_count() > 0) { | |
2262 __ movp(temp, Operand(rsp, arg_count() * kPointerSize)); | |
2263 Handle<Map> map = isolate()->factory()->heap_number_map(); | |
2264 __ CheckMap(temp, map, &tail, DO_SMI_CHECK); | |
2265 | |
2266 __ movsd(xmm_temp1, FieldOperand(rax, HeapNumber::kValueOffset)); | |
2267 | |
2268 // If the number is >0, it doesn't round to -0 | |
2269 __ xorps(xmm_temp2, xmm_temp2); | |
2270 __ ucomisd(xmm_temp1, xmm_temp2); | |
2271 __ j(greater, &tail, Label::kNear); | |
2272 | |
2273 // If the number is <=-1, it doesn't round to -0 | |
2274 static int64_t minus_one = V8_INT64_C(0xbff0000000000000); // -1 | |
2275 __ movq(temp, minus_one); | |
2276 __ movq(xmm_temp2, temp); | |
2277 __ ucomisd(xmm_temp1, xmm_temp2); | |
2278 __ j(less_equal, &tail, Label::kNear); | |
2279 | |
2280 // +0 doesn't round to -0. | |
2281 __ movmskpd(temp, xmm_temp1); | |
2282 __ testq(temp, Immediate(1)); | |
2283 __ j(zero, &tail, Label::kNear); | |
2284 | |
2285 __ Move(FieldOperand(vector, slot, times_pointer_size, | |
2286 FixedArray::kHeaderSize + kPointerSize), | |
2287 Smi::FromInt(kHasReturnedMinusZeroSentinel)); | |
2288 } | |
2289 | |
2290 __ bind(&tail); | |
2291 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); | |
2292 | |
2293 // Unreachable. | |
2294 __ int3(); | |
2295 | |
2296 __ bind(&miss); | |
2297 GenerateMiss(masm); | |
2298 __ jmp(&tail); | |
2299 } | |
2300 | |
2301 | |
2302 void CallICStub::Generate(MacroAssembler* masm) { | 2147 void CallICStub::Generate(MacroAssembler* masm) { |
2303 // rdi - function | 2148 // rdi - function |
2304 // rdx - slot id | 2149 // rdx - slot id |
2305 // rbx - vector | 2150 // rbx - vector |
2306 Isolate* isolate = masm->isolate(); | 2151 Isolate* isolate = masm->isolate(); |
2307 const int with_types_offset = | 2152 const int with_types_offset = |
2308 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | 2153 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
2309 const int generic_offset = | 2154 const int generic_offset = |
2310 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | 2155 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
2311 Label extra_checks_or_miss, slow_start; | 2156 Label extra_checks_or_miss, slow_start; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2401 // Goto miss case if we do not have a function. | 2246 // Goto miss case if we do not have a function. |
2402 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); | 2247 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
2403 __ j(not_equal, &miss); | 2248 __ j(not_equal, &miss); |
2404 | 2249 |
2405 // Make sure the function is not the Array() function, which requires special | 2250 // Make sure the function is not the Array() function, which requires special |
2406 // behavior on MISS. | 2251 // behavior on MISS. |
2407 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx); | 2252 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx); |
2408 __ cmpp(rdi, rcx); | 2253 __ cmpp(rdi, rcx); |
2409 __ j(equal, &miss); | 2254 __ j(equal, &miss); |
2410 | 2255 |
2411 __ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | |
2412 __ movp(rax, FieldOperand(rax, SharedFunctionInfo::kFunctionDataOffset)); | |
2413 __ Cmp(rax, Smi::FromInt(0)); | |
2414 __ j(not_equal, &miss); | |
2415 | |
2416 // Update stats. | 2256 // Update stats. |
2417 __ SmiAddConstant(FieldOperand(rbx, with_types_offset), Smi::FromInt(1)); | 2257 __ SmiAddConstant(FieldOperand(rbx, with_types_offset), Smi::FromInt(1)); |
2418 | 2258 |
2419 // Store the function. Use a stub since we need a frame for allocation. | 2259 // Store the function. Use a stub since we need a frame for allocation. |
2420 // rbx - vector | 2260 // rbx - vector |
2421 // rdx - slot (needs to be in smi form) | 2261 // rdx - slot (needs to be in smi form) |
2422 // rdi - function | 2262 // rdi - function |
2423 { | 2263 { |
2424 FrameScope scope(masm, StackFrame::INTERNAL); | 2264 FrameScope scope(masm, StackFrame::INTERNAL); |
2425 CreateWeakCellStub create_stub(isolate); | 2265 CreateWeakCellStub create_stub(isolate); |
(...skipping 2295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4721 } | 4561 } |
4722 | 4562 |
4723 | 4563 |
4724 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) { | 4564 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) { |
4725 EmitLoadTypeFeedbackVector(masm, rbx); | 4565 EmitLoadTypeFeedbackVector(masm, rbx); |
4726 CallIC_ArrayStub stub(isolate(), state()); | 4566 CallIC_ArrayStub stub(isolate(), state()); |
4727 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | 4567 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); |
4728 } | 4568 } |
4729 | 4569 |
4730 | 4570 |
4731 void CallIC_RoundTrampolineStub::Generate(MacroAssembler* masm) { | |
4732 EmitLoadTypeFeedbackVector(masm, rbx); | |
4733 CallIC_RoundStub stub(isolate(), state()); | |
4734 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | |
4735 } | |
4736 | |
4737 | |
4738 void CallIC_FloorTrampolineStub::Generate(MacroAssembler* masm) { | |
4739 EmitLoadTypeFeedbackVector(masm, rbx); | |
4740 CallIC_FloorStub stub(isolate(), state()); | |
4741 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | |
4742 } | |
4743 | |
4744 | |
4745 void CallIC_CeilTrampolineStub::Generate(MacroAssembler* masm) { | |
4746 EmitLoadTypeFeedbackVector(masm, rbx); | |
4747 CallIC_CeilStub stub(isolate(), state()); | |
4748 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | |
4749 } | |
4750 | |
4751 | |
4752 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 4571 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { |
4753 if (masm->isolate()->function_entry_hook() != NULL) { | 4572 if (masm->isolate()->function_entry_hook() != NULL) { |
4754 ProfileEntryHookStub stub(masm->isolate()); | 4573 ProfileEntryHookStub stub(masm->isolate()); |
4755 masm->CallStub(&stub); | 4574 masm->CallStub(&stub); |
4756 } | 4575 } |
4757 } | 4576 } |
4758 | 4577 |
4759 | 4578 |
4760 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { | 4579 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { |
4761 // This stub can be called from essentially anywhere, so it needs to save | 4580 // This stub can be called from essentially anywhere, so it needs to save |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5531 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, | 5350 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, |
5532 kStackSpace, nullptr, return_value_operand, NULL); | 5351 kStackSpace, nullptr, return_value_operand, NULL); |
5533 } | 5352 } |
5534 | 5353 |
5535 | 5354 |
5536 #undef __ | 5355 #undef __ |
5537 | 5356 |
5538 } } // namespace v8::internal | 5357 } } // namespace v8::internal |
5539 | 5358 |
5540 #endif // V8_TARGET_ARCH_X64 | 5359 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |