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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 2271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2282 __ Add(x4, x4, Code::kHeaderSize - kHeapObjectTag); | 2282 __ Add(x4, x4, Code::kHeaderSize - kHeapObjectTag); |
2283 __ Br(x4); | 2283 __ Br(x4); |
2284 | 2284 |
2285 __ Bind(&non_function); | 2285 __ Bind(&non_function); |
2286 __ Mov(x3, function); | 2286 __ Mov(x3, function); |
2287 __ Jump(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2287 __ Jump(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2288 } | 2288 } |
2289 | 2289 |
2290 | 2290 |
2291 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { | 2291 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { |
| 2292 // x0 - number of arguments |
2292 // x1 - function | 2293 // x1 - function |
2293 // x3 - slot id | 2294 // x3 - slot id |
2294 // x2 - vector | 2295 // x2 - vector |
2295 // x4 - allocation site (loaded from vector[slot]) | 2296 // x4 - allocation site (loaded from vector[slot]) |
2296 Register function = x1; | 2297 Register function = x1; |
2297 Register feedback_vector = x2; | 2298 Register feedback_vector = x2; |
2298 Register index = x3; | 2299 Register index = x3; |
2299 Register allocation_site = x4; | 2300 Register allocation_site = x4; |
2300 Register scratch = x5; | 2301 Register scratch = x5; |
2301 | 2302 |
2302 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, scratch); | 2303 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, scratch); |
2303 __ Cmp(function, scratch); | 2304 __ Cmp(function, scratch); |
2304 __ B(ne, miss); | 2305 __ B(ne, miss); |
2305 | 2306 |
2306 __ Mov(x0, Operand(arg_count())); | |
2307 | |
2308 // Increment the call count for monomorphic function calls. | 2307 // Increment the call count for monomorphic function calls. |
2309 __ Add(feedback_vector, feedback_vector, | 2308 __ Add(feedback_vector, feedback_vector, |
2310 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 2309 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
2311 __ Add(feedback_vector, feedback_vector, | 2310 __ Add(feedback_vector, feedback_vector, |
2312 Operand(FixedArray::kHeaderSize + kPointerSize)); | 2311 Operand(FixedArray::kHeaderSize + kPointerSize)); |
2313 __ Ldr(index, FieldMemOperand(feedback_vector, 0)); | 2312 __ Ldr(index, FieldMemOperand(feedback_vector, 0)); |
2314 __ Add(index, index, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 2313 __ Add(index, index, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
2315 __ Str(index, FieldMemOperand(feedback_vector, 0)); | 2314 __ Str(index, FieldMemOperand(feedback_vector, 0)); |
2316 | 2315 |
2317 // Set up arguments for the array constructor stub. | 2316 // Set up arguments for the array constructor stub. |
2318 Register allocation_site_arg = feedback_vector; | 2317 Register allocation_site_arg = feedback_vector; |
2319 Register new_target_arg = index; | 2318 Register new_target_arg = index; |
2320 __ Mov(allocation_site_arg, allocation_site); | 2319 __ Mov(allocation_site_arg, allocation_site); |
2321 __ Mov(new_target_arg, function); | 2320 __ Mov(new_target_arg, function); |
2322 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 2321 if (argc_in_register()) { |
2323 __ TailCallStub(&stub); | 2322 // Pass a default ArgumentCountKey::Any since the argc is only available |
| 2323 // in r0. We do not have the actual count here. |
| 2324 ArrayConstructorStub stub(masm->isolate()); |
| 2325 __ TailCallStub(&stub); |
| 2326 } else { |
| 2327 // arg_count() is expected in r0 if the arg_count() >= 2 |
| 2328 // (ArgumentCountKey::MORE_THAN_ONE). |
| 2329 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| 2330 __ TailCallStub(&stub); |
| 2331 } |
2324 } | 2332 } |
2325 | 2333 |
2326 | 2334 |
2327 void CallICStub::Generate(MacroAssembler* masm) { | 2335 void CallICStub::Generate(MacroAssembler* masm) { |
2328 ASM_LOCATION("CallICStub"); | 2336 ASM_LOCATION("CallICStub"); |
2329 | 2337 |
| 2338 // x0 - number of arguments if argc_in_register() is true |
2330 // x1 - function | 2339 // x1 - function |
2331 // x3 - slot id (Smi) | 2340 // x3 - slot id (Smi) |
2332 // x2 - vector | 2341 // x2 - vector |
2333 Label extra_checks_or_miss, call, call_function; | 2342 Label extra_checks_or_miss, call, call_function; |
2334 int argc = arg_count(); | 2343 if (!argc_in_register()) { |
2335 ParameterCount actual(argc); | 2344 __ Mov(x0, arg_count()); |
| 2345 } |
2336 | 2346 |
2337 Register function = x1; | 2347 Register function = x1; |
2338 Register feedback_vector = x2; | 2348 Register feedback_vector = x2; |
2339 Register index = x3; | 2349 Register index = x3; |
2340 | 2350 |
2341 // The checks. First, does x1 match the recorded monomorphic target? | 2351 // The checks. First, does x1 match the recorded monomorphic target? |
2342 __ Add(x4, feedback_vector, | 2352 __ Add(x4, feedback_vector, |
2343 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 2353 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
2344 __ Ldr(x4, FieldMemOperand(x4, FixedArray::kHeaderSize)); | 2354 __ Ldr(x4, FieldMemOperand(x4, FixedArray::kHeaderSize)); |
2345 | 2355 |
(...skipping 22 matching lines...) Expand all Loading... |
2368 // Increment the call count for monomorphic function calls. | 2378 // Increment the call count for monomorphic function calls. |
2369 __ Add(feedback_vector, feedback_vector, | 2379 __ Add(feedback_vector, feedback_vector, |
2370 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 2380 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
2371 __ Add(feedback_vector, feedback_vector, | 2381 __ Add(feedback_vector, feedback_vector, |
2372 Operand(FixedArray::kHeaderSize + kPointerSize)); | 2382 Operand(FixedArray::kHeaderSize + kPointerSize)); |
2373 __ Ldr(index, FieldMemOperand(feedback_vector, 0)); | 2383 __ Ldr(index, FieldMemOperand(feedback_vector, 0)); |
2374 __ Add(index, index, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 2384 __ Add(index, index, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
2375 __ Str(index, FieldMemOperand(feedback_vector, 0)); | 2385 __ Str(index, FieldMemOperand(feedback_vector, 0)); |
2376 | 2386 |
2377 __ Bind(&call_function); | 2387 __ Bind(&call_function); |
2378 __ Mov(x0, argc); | |
2379 __ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(), | 2388 __ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(), |
2380 tail_call_mode()), | 2389 tail_call_mode()), |
2381 RelocInfo::CODE_TARGET); | 2390 RelocInfo::CODE_TARGET); |
2382 | 2391 |
2383 __ bind(&extra_checks_or_miss); | 2392 __ bind(&extra_checks_or_miss); |
2384 Label uninitialized, miss, not_allocation_site; | 2393 Label uninitialized, miss, not_allocation_site; |
2385 | 2394 |
2386 __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &call); | 2395 __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &call); |
2387 | 2396 |
2388 __ Ldr(x5, FieldMemOperand(x4, HeapObject::kMapOffset)); | 2397 __ Ldr(x5, FieldMemOperand(x4, HeapObject::kMapOffset)); |
(...skipping 14 matching lines...) Expand all Loading... |
2403 // We are going megamorphic. If the feedback is a JSFunction, it is fine | 2412 // We are going megamorphic. If the feedback is a JSFunction, it is fine |
2404 // to handle it here. More complex cases are dealt with in the runtime. | 2413 // to handle it here. More complex cases are dealt with in the runtime. |
2405 __ AssertNotSmi(x4); | 2414 __ AssertNotSmi(x4); |
2406 __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss); | 2415 __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss); |
2407 __ Add(x4, feedback_vector, | 2416 __ Add(x4, feedback_vector, |
2408 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 2417 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
2409 __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex); | 2418 __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex); |
2410 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize)); | 2419 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize)); |
2411 | 2420 |
2412 __ Bind(&call); | 2421 __ Bind(&call); |
2413 __ Mov(x0, argc); | |
2414 __ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()), | 2422 __ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()), |
2415 RelocInfo::CODE_TARGET); | 2423 RelocInfo::CODE_TARGET); |
2416 | 2424 |
2417 __ bind(&uninitialized); | 2425 __ bind(&uninitialized); |
2418 | 2426 |
2419 // We are going monomorphic, provided we actually have a JSFunction. | 2427 // We are going monomorphic, provided we actually have a JSFunction. |
2420 __ JumpIfSmi(function, &miss); | 2428 __ JumpIfSmi(function, &miss); |
2421 | 2429 |
2422 // Goto miss case if we do not have a function. | 2430 // Goto miss case if we do not have a function. |
2423 __ JumpIfNotObjectType(function, x5, x5, JS_FUNCTION_TYPE, &miss); | 2431 __ JumpIfNotObjectType(function, x5, x5, JS_FUNCTION_TYPE, &miss); |
(...skipping 17 matching lines...) Expand all Loading... |
2441 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 2449 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
2442 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize + kPointerSize)); | 2450 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize + kPointerSize)); |
2443 | 2451 |
2444 // Store the function. Use a stub since we need a frame for allocation. | 2452 // Store the function. Use a stub since we need a frame for allocation. |
2445 // x2 - vector | 2453 // x2 - vector |
2446 // x3 - slot | 2454 // x3 - slot |
2447 // x1 - function | 2455 // x1 - function |
2448 { | 2456 { |
2449 FrameScope scope(masm, StackFrame::INTERNAL); | 2457 FrameScope scope(masm, StackFrame::INTERNAL); |
2450 CreateWeakCellStub create_stub(masm->isolate()); | 2458 CreateWeakCellStub create_stub(masm->isolate()); |
| 2459 __ SmiTag(x0); |
| 2460 __ Push(x0); |
2451 __ Push(function); | 2461 __ Push(function); |
2452 __ CallStub(&create_stub); | 2462 __ CallStub(&create_stub); |
2453 __ Pop(function); | 2463 __ Pop(function); |
| 2464 __ Pop(x0); |
| 2465 __ SmiUntag(x0); |
2454 } | 2466 } |
2455 | 2467 |
2456 __ B(&call_function); | 2468 __ B(&call_function); |
2457 | 2469 |
2458 // We are here because tracing is on or we encountered a MISS case we can't | 2470 // We are here because tracing is on or we encountered a MISS case we can't |
2459 // handle here. | 2471 // handle here. |
2460 __ bind(&miss); | 2472 __ bind(&miss); |
2461 GenerateMiss(masm); | 2473 GenerateMiss(masm); |
2462 | 2474 |
2463 __ B(&call); | 2475 __ B(&call); |
2464 } | 2476 } |
2465 | 2477 |
2466 | 2478 |
2467 void CallICStub::GenerateMiss(MacroAssembler* masm) { | 2479 void CallICStub::GenerateMiss(MacroAssembler* masm) { |
2468 ASM_LOCATION("CallICStub[Miss]"); | 2480 ASM_LOCATION("CallICStub[Miss]"); |
2469 | 2481 |
2470 FrameScope scope(masm, StackFrame::INTERNAL); | 2482 FrameScope scope(masm, StackFrame::INTERNAL); |
2471 | 2483 |
| 2484 // Store number of arguments. |
| 2485 __ SmiTag(x0); |
| 2486 __ Push(x0); |
| 2487 |
2472 // Push the receiver and the function and feedback info. | 2488 // Push the receiver and the function and feedback info. |
2473 __ Push(x1, x2, x3); | 2489 __ Push(x1, x2, x3); |
2474 | 2490 |
2475 // Call the entry. | 2491 // Call the entry. |
2476 __ CallRuntime(Runtime::kCallIC_Miss); | 2492 __ CallRuntime(Runtime::kCallIC_Miss); |
2477 | 2493 |
2478 // Move result to edi and exit the internal frame. | 2494 // Move result to edi and exit the internal frame. |
2479 __ Mov(x1, x0); | 2495 __ Mov(x1, x0); |
| 2496 |
| 2497 // Restore number of arguments. |
| 2498 __ Pop(x0); |
| 2499 __ SmiUntag(x0); |
2480 } | 2500 } |
2481 | 2501 |
2482 | 2502 |
2483 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 2503 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
2484 // If the receiver is a smi trigger the non-string case. | 2504 // If the receiver is a smi trigger the non-string case. |
2485 if (check_mode_ == RECEIVER_IS_UNKNOWN) { | 2505 if (check_mode_ == RECEIVER_IS_UNKNOWN) { |
2486 __ JumpIfSmi(object_, receiver_not_string_); | 2506 __ JumpIfSmi(object_, receiver_not_string_); |
2487 | 2507 |
2488 // Fetch the instance type of the receiver into result register. | 2508 // Fetch the instance type of the receiver into result register. |
2489 __ Ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); | 2509 __ Ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); |
(...skipping 3505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5995 return_value_operand, NULL); | 6015 return_value_operand, NULL); |
5996 } | 6016 } |
5997 | 6017 |
5998 | 6018 |
5999 #undef __ | 6019 #undef __ |
6000 | 6020 |
6001 } // namespace internal | 6021 } // namespace internal |
6002 } // namespace v8 | 6022 } // namespace v8 |
6003 | 6023 |
6004 #endif // V8_TARGET_ARCH_ARM64 | 6024 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |