| 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 #include "src/code-stubs.h" | 5 #include "src/code-stubs.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 2364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2375 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 2375 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); |
| 2376 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 2376 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); |
| 2377 Node* value = assembler->Word32Xor(lhs_value, rhs_value); | 2377 Node* value = assembler->Word32Xor(lhs_value, rhs_value); |
| 2378 Node* result = assembler->ChangeInt32ToTagged(value); | 2378 Node* result = assembler->ChangeInt32ToTagged(value); |
| 2379 return result; | 2379 return result; |
| 2380 } | 2380 } |
| 2381 | 2381 |
| 2382 // static | 2382 // static |
| 2383 compiler::Node* IncStub::Generate(CodeStubAssembler* assembler, | 2383 compiler::Node* IncStub::Generate(CodeStubAssembler* assembler, |
| 2384 compiler::Node* value, | 2384 compiler::Node* value, |
| 2385 compiler::Node* context) { | 2385 compiler::Node* context, |
| 2386 compiler::Node* type_feedback_vector, |
| 2387 compiler::Node* slot_id) { |
| 2386 typedef CodeStubAssembler::Label Label; | 2388 typedef CodeStubAssembler::Label Label; |
| 2387 typedef compiler::Node Node; | 2389 typedef compiler::Node Node; |
| 2388 typedef CodeStubAssembler::Variable Variable; | 2390 typedef CodeStubAssembler::Variable Variable; |
| 2389 | 2391 |
| 2390 // Shared entry for floating point increment. | 2392 // Shared entry for floating point increment. |
| 2391 Label do_finc(assembler), end(assembler); | 2393 Label do_finc(assembler), end(assembler); |
| 2392 Variable var_finc_value(assembler, MachineRepresentation::kFloat64); | 2394 Variable var_finc_value(assembler, MachineRepresentation::kFloat64); |
| 2393 | 2395 |
| 2394 // We might need to try again due to ToNumber conversion. | 2396 // We might need to try again due to ToNumber conversion. |
| 2395 Variable value_var(assembler, MachineRepresentation::kTagged); | 2397 Variable value_var(assembler, MachineRepresentation::kTagged); |
| 2396 Variable result_var(assembler, MachineRepresentation::kTagged); | 2398 Variable result_var(assembler, MachineRepresentation::kTagged); |
| 2397 Label start(assembler, &value_var); | 2399 Variable var_type_feedback(assembler, MachineRepresentation::kWord32); |
| 2400 Variable* loop_vars[] = {&value_var, &var_type_feedback}; |
| 2401 Label start(assembler, 2, loop_vars); |
| 2398 value_var.Bind(value); | 2402 value_var.Bind(value); |
| 2403 var_type_feedback.Bind( |
| 2404 assembler->Int32Constant(BinaryOperationFeedback::kNone)); |
| 2399 assembler->Goto(&start); | 2405 assembler->Goto(&start); |
| 2400 assembler->Bind(&start); | 2406 assembler->Bind(&start); |
| 2401 { | 2407 { |
| 2402 value = value_var.value(); | 2408 value = value_var.value(); |
| 2403 | 2409 |
| 2404 Label if_issmi(assembler), if_isnotsmi(assembler); | 2410 Label if_issmi(assembler), if_isnotsmi(assembler); |
| 2405 assembler->Branch(assembler->WordIsSmi(value), &if_issmi, &if_isnotsmi); | 2411 assembler->Branch(assembler->WordIsSmi(value), &if_issmi, &if_isnotsmi); |
| 2406 | 2412 |
| 2407 assembler->Bind(&if_issmi); | 2413 assembler->Bind(&if_issmi); |
| 2408 { | 2414 { |
| 2409 // Try fast Smi addition first. | 2415 // Try fast Smi addition first. |
| 2410 Node* one = assembler->SmiConstant(Smi::FromInt(1)); | 2416 Node* one = assembler->SmiConstant(Smi::FromInt(1)); |
| 2411 Node* pair = assembler->SmiAddWithOverflow(value, one); | 2417 Node* pair = assembler->SmiAddWithOverflow(value, one); |
| 2412 Node* overflow = assembler->Projection(1, pair); | 2418 Node* overflow = assembler->Projection(1, pair); |
| 2413 | 2419 |
| 2414 // Check if the Smi addition overflowed. | 2420 // Check if the Smi addition overflowed. |
| 2415 Label if_overflow(assembler), if_notoverflow(assembler); | 2421 Label if_overflow(assembler), if_notoverflow(assembler); |
| 2416 assembler->Branch(overflow, &if_overflow, &if_notoverflow); | 2422 assembler->Branch(overflow, &if_overflow, &if_notoverflow); |
| 2417 | 2423 |
| 2418 assembler->Bind(&if_notoverflow); | 2424 assembler->Bind(&if_notoverflow); |
| 2425 var_type_feedback.Bind(assembler->Word32Or( |
| 2426 var_type_feedback.value(), |
| 2427 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall))); |
| 2419 result_var.Bind(assembler->Projection(0, pair)); | 2428 result_var.Bind(assembler->Projection(0, pair)); |
| 2420 assembler->Goto(&end); | 2429 assembler->Goto(&end); |
| 2421 | 2430 |
| 2422 assembler->Bind(&if_overflow); | 2431 assembler->Bind(&if_overflow); |
| 2423 { | 2432 { |
| 2424 var_finc_value.Bind(assembler->SmiToFloat64(value)); | 2433 var_finc_value.Bind(assembler->SmiToFloat64(value)); |
| 2425 assembler->Goto(&do_finc); | 2434 assembler->Goto(&do_finc); |
| 2426 } | 2435 } |
| 2427 } | 2436 } |
| 2428 | 2437 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2441 // Load the HeapNumber value. | 2450 // Load the HeapNumber value. |
| 2442 var_finc_value.Bind(assembler->LoadHeapNumberValue(value)); | 2451 var_finc_value.Bind(assembler->LoadHeapNumberValue(value)); |
| 2443 assembler->Goto(&do_finc); | 2452 assembler->Goto(&do_finc); |
| 2444 } | 2453 } |
| 2445 | 2454 |
| 2446 assembler->Bind(&if_valuenotnumber); | 2455 assembler->Bind(&if_valuenotnumber); |
| 2447 { | 2456 { |
| 2448 // Convert to a Number first and try again. | 2457 // Convert to a Number first and try again. |
| 2449 Callable callable = | 2458 Callable callable = |
| 2450 CodeFactory::NonNumberToNumber(assembler->isolate()); | 2459 CodeFactory::NonNumberToNumber(assembler->isolate()); |
| 2460 var_type_feedback.Bind( |
| 2461 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 2451 value_var.Bind(assembler->CallStub(callable, context, value)); | 2462 value_var.Bind(assembler->CallStub(callable, context, value)); |
| 2452 assembler->Goto(&start); | 2463 assembler->Goto(&start); |
| 2453 } | 2464 } |
| 2454 } | 2465 } |
| 2455 } | 2466 } |
| 2456 | 2467 |
| 2457 assembler->Bind(&do_finc); | 2468 assembler->Bind(&do_finc); |
| 2458 { | 2469 { |
| 2459 Node* finc_value = var_finc_value.value(); | 2470 Node* finc_value = var_finc_value.value(); |
| 2460 Node* one = assembler->Float64Constant(1.0); | 2471 Node* one = assembler->Float64Constant(1.0); |
| 2461 Node* finc_result = assembler->Float64Add(finc_value, one); | 2472 Node* finc_result = assembler->Float64Add(finc_value, one); |
| 2473 var_type_feedback.Bind(assembler->Word32Or( |
| 2474 var_type_feedback.value(), |
| 2475 assembler->Int32Constant(BinaryOperationFeedback::kNumber))); |
| 2462 result_var.Bind(assembler->ChangeFloat64ToTagged(finc_result)); | 2476 result_var.Bind(assembler->ChangeFloat64ToTagged(finc_result)); |
| 2463 assembler->Goto(&end); | 2477 assembler->Goto(&end); |
| 2464 } | 2478 } |
| 2465 | 2479 |
| 2466 assembler->Bind(&end); | 2480 assembler->Bind(&end); |
| 2481 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
| 2482 slot_id); |
| 2467 return result_var.value(); | 2483 return result_var.value(); |
| 2468 } | 2484 } |
| 2469 | 2485 |
| 2470 // static | 2486 // static |
| 2471 compiler::Node* DecStub::Generate(CodeStubAssembler* assembler, | 2487 compiler::Node* DecStub::Generate(CodeStubAssembler* assembler, |
| 2472 compiler::Node* value, | 2488 compiler::Node* value, |
| 2473 compiler::Node* context) { | 2489 compiler::Node* context, |
| 2490 compiler::Node* type_feedback_vector, |
| 2491 compiler::Node* slot_id) { |
| 2474 typedef CodeStubAssembler::Label Label; | 2492 typedef CodeStubAssembler::Label Label; |
| 2475 typedef compiler::Node Node; | 2493 typedef compiler::Node Node; |
| 2476 typedef CodeStubAssembler::Variable Variable; | 2494 typedef CodeStubAssembler::Variable Variable; |
| 2477 | 2495 |
| 2478 // Shared entry for floating point decrement. | 2496 // Shared entry for floating point decrement. |
| 2479 Label do_fdec(assembler), end(assembler); | 2497 Label do_fdec(assembler), end(assembler); |
| 2480 Variable var_fdec_value(assembler, MachineRepresentation::kFloat64); | 2498 Variable var_fdec_value(assembler, MachineRepresentation::kFloat64); |
| 2481 | 2499 |
| 2482 // We might need to try again due to ToNumber conversion. | 2500 // We might need to try again due to ToNumber conversion. |
| 2483 Variable value_var(assembler, MachineRepresentation::kTagged); | 2501 Variable value_var(assembler, MachineRepresentation::kTagged); |
| 2484 Variable result_var(assembler, MachineRepresentation::kTagged); | 2502 Variable result_var(assembler, MachineRepresentation::kTagged); |
| 2485 Label start(assembler, &value_var); | 2503 Variable var_type_feedback(assembler, MachineRepresentation::kWord32); |
| 2504 Variable* loop_vars[] = {&value_var, &var_type_feedback}; |
| 2505 Label start(assembler, 2, loop_vars); |
| 2506 var_type_feedback.Bind( |
| 2507 assembler->Int32Constant(BinaryOperationFeedback::kNone)); |
| 2486 value_var.Bind(value); | 2508 value_var.Bind(value); |
| 2487 assembler->Goto(&start); | 2509 assembler->Goto(&start); |
| 2488 assembler->Bind(&start); | 2510 assembler->Bind(&start); |
| 2489 { | 2511 { |
| 2490 value = value_var.value(); | 2512 value = value_var.value(); |
| 2491 | 2513 |
| 2492 Label if_issmi(assembler), if_isnotsmi(assembler); | 2514 Label if_issmi(assembler), if_isnotsmi(assembler); |
| 2493 assembler->Branch(assembler->WordIsSmi(value), &if_issmi, &if_isnotsmi); | 2515 assembler->Branch(assembler->WordIsSmi(value), &if_issmi, &if_isnotsmi); |
| 2494 | 2516 |
| 2495 assembler->Bind(&if_issmi); | 2517 assembler->Bind(&if_issmi); |
| 2496 { | 2518 { |
| 2497 // Try fast Smi subtraction first. | 2519 // Try fast Smi subtraction first. |
| 2498 Node* one = assembler->SmiConstant(Smi::FromInt(1)); | 2520 Node* one = assembler->SmiConstant(Smi::FromInt(1)); |
| 2499 Node* pair = assembler->SmiSubWithOverflow(value, one); | 2521 Node* pair = assembler->SmiSubWithOverflow(value, one); |
| 2500 Node* overflow = assembler->Projection(1, pair); | 2522 Node* overflow = assembler->Projection(1, pair); |
| 2501 | 2523 |
| 2502 // Check if the Smi subtraction overflowed. | 2524 // Check if the Smi subtraction overflowed. |
| 2503 Label if_overflow(assembler), if_notoverflow(assembler); | 2525 Label if_overflow(assembler), if_notoverflow(assembler); |
| 2504 assembler->Branch(overflow, &if_overflow, &if_notoverflow); | 2526 assembler->Branch(overflow, &if_overflow, &if_notoverflow); |
| 2505 | 2527 |
| 2506 assembler->Bind(&if_notoverflow); | 2528 assembler->Bind(&if_notoverflow); |
| 2529 var_type_feedback.Bind(assembler->Word32Or( |
| 2530 var_type_feedback.value(), |
| 2531 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall))); |
| 2507 result_var.Bind(assembler->Projection(0, pair)); | 2532 result_var.Bind(assembler->Projection(0, pair)); |
| 2508 assembler->Goto(&end); | 2533 assembler->Goto(&end); |
| 2509 | 2534 |
| 2510 assembler->Bind(&if_overflow); | 2535 assembler->Bind(&if_overflow); |
| 2511 { | 2536 { |
| 2512 var_fdec_value.Bind(assembler->SmiToFloat64(value)); | 2537 var_fdec_value.Bind(assembler->SmiToFloat64(value)); |
| 2513 assembler->Goto(&do_fdec); | 2538 assembler->Goto(&do_fdec); |
| 2514 } | 2539 } |
| 2515 } | 2540 } |
| 2516 | 2541 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2529 // Load the HeapNumber value. | 2554 // Load the HeapNumber value. |
| 2530 var_fdec_value.Bind(assembler->LoadHeapNumberValue(value)); | 2555 var_fdec_value.Bind(assembler->LoadHeapNumberValue(value)); |
| 2531 assembler->Goto(&do_fdec); | 2556 assembler->Goto(&do_fdec); |
| 2532 } | 2557 } |
| 2533 | 2558 |
| 2534 assembler->Bind(&if_valuenotnumber); | 2559 assembler->Bind(&if_valuenotnumber); |
| 2535 { | 2560 { |
| 2536 // Convert to a Number first and try again. | 2561 // Convert to a Number first and try again. |
| 2537 Callable callable = | 2562 Callable callable = |
| 2538 CodeFactory::NonNumberToNumber(assembler->isolate()); | 2563 CodeFactory::NonNumberToNumber(assembler->isolate()); |
| 2564 var_type_feedback.Bind( |
| 2565 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 2539 value_var.Bind(assembler->CallStub(callable, context, value)); | 2566 value_var.Bind(assembler->CallStub(callable, context, value)); |
| 2540 assembler->Goto(&start); | 2567 assembler->Goto(&start); |
| 2541 } | 2568 } |
| 2542 } | 2569 } |
| 2543 } | 2570 } |
| 2544 | 2571 |
| 2545 assembler->Bind(&do_fdec); | 2572 assembler->Bind(&do_fdec); |
| 2546 { | 2573 { |
| 2547 Node* fdec_value = var_fdec_value.value(); | 2574 Node* fdec_value = var_fdec_value.value(); |
| 2548 Node* one = assembler->Float64Constant(1.0); | 2575 Node* one = assembler->Float64Constant(1.0); |
| 2549 Node* fdec_result = assembler->Float64Sub(fdec_value, one); | 2576 Node* fdec_result = assembler->Float64Sub(fdec_value, one); |
| 2577 var_type_feedback.Bind(assembler->Word32Or( |
| 2578 var_type_feedback.value(), |
| 2579 assembler->Int32Constant(BinaryOperationFeedback::kNumber))); |
| 2550 result_var.Bind(assembler->ChangeFloat64ToTagged(fdec_result)); | 2580 result_var.Bind(assembler->ChangeFloat64ToTagged(fdec_result)); |
| 2551 assembler->Goto(&end); | 2581 assembler->Goto(&end); |
| 2552 } | 2582 } |
| 2553 | 2583 |
| 2554 assembler->Bind(&end); | 2584 assembler->Bind(&end); |
| 2585 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
| 2586 slot_id); |
| 2555 return result_var.value(); | 2587 return result_var.value(); |
| 2556 } | 2588 } |
| 2557 | 2589 |
| 2558 // ES6 section 7.1.13 ToObject (argument) | 2590 // ES6 section 7.1.13 ToObject (argument) |
| 2559 void ToObjectStub::GenerateAssembly(CodeStubAssembler* assembler) const { | 2591 void ToObjectStub::GenerateAssembly(CodeStubAssembler* assembler) const { |
| 2560 typedef compiler::Node Node; | 2592 typedef compiler::Node Node; |
| 2561 typedef CodeStubAssembler::Label Label; | 2593 typedef CodeStubAssembler::Label Label; |
| 2562 typedef CodeStubAssembler::Variable Variable; | 2594 typedef CodeStubAssembler::Variable Variable; |
| 2563 | 2595 |
| 2564 Label if_number(assembler, Label::kDeferred), if_notsmi(assembler), | 2596 Label if_number(assembler, Label::kDeferred), if_notsmi(assembler), |
| (...skipping 3252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5817 if (type->Is(Type::UntaggedPointer())) { | 5849 if (type->Is(Type::UntaggedPointer())) { |
| 5818 return Representation::External(); | 5850 return Representation::External(); |
| 5819 } | 5851 } |
| 5820 | 5852 |
| 5821 DCHECK(!type->Is(Type::Untagged())); | 5853 DCHECK(!type->Is(Type::Untagged())); |
| 5822 return Representation::Tagged(); | 5854 return Representation::Tagged(); |
| 5823 } | 5855 } |
| 5824 | 5856 |
| 5825 } // namespace internal | 5857 } // namespace internal |
| 5826 } // namespace v8 | 5858 } // namespace v8 |
| OLD | NEW |