| 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 3531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3542 assembler->Bind(&return_zero); | 3542 assembler->Bind(&return_zero); |
| 3543 assembler->Return(assembler->SmiConstant(Smi::FromInt(0))); | 3543 assembler->Return(assembler->SmiConstant(Smi::FromInt(0))); |
| 3544 } | 3544 } |
| 3545 } | 3545 } |
| 3546 | 3546 |
| 3547 void ToBooleanStub::GenerateAssembly(CodeStubAssembler* assembler) const { | 3547 void ToBooleanStub::GenerateAssembly(CodeStubAssembler* assembler) const { |
| 3548 typedef compiler::Node Node; | 3548 typedef compiler::Node Node; |
| 3549 typedef CodeStubAssembler::Label Label; | 3549 typedef CodeStubAssembler::Label Label; |
| 3550 | 3550 |
| 3551 Node* value = assembler->Parameter(0); | 3551 Node* value = assembler->Parameter(0); |
| 3552 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); | 3552 Label if_valueissmi(assembler), if_valueisnotsmi(assembler), |
| 3553 return_true(assembler), return_false(assembler); |
| 3553 | 3554 |
| 3554 // Check if {value} is a Smi or a HeapObject. | 3555 // Check if {value} is a Smi or a HeapObject. |
| 3555 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi, | 3556 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi, |
| 3556 &if_valueisnotsmi); | 3557 &if_valueisnotsmi); |
| 3557 | 3558 |
| 3558 assembler->Bind(&if_valueissmi); | 3559 assembler->Bind(&if_valueissmi); |
| 3559 { | 3560 { |
| 3560 // The {value} is a Smi, only need to check against zero. | 3561 // The {value} is a Smi, only need to check against zero. |
| 3561 Label if_valueiszero(assembler), if_valueisnotzero(assembler); | |
| 3562 assembler->Branch(assembler->SmiEqual(value, assembler->SmiConstant(0)), | 3562 assembler->Branch(assembler->SmiEqual(value, assembler->SmiConstant(0)), |
| 3563 &if_valueiszero, &if_valueisnotzero); | 3563 &return_false, &return_true); |
| 3564 | |
| 3565 assembler->Bind(&if_valueiszero); | |
| 3566 assembler->Return(assembler->BooleanConstant(false)); | |
| 3567 | |
| 3568 assembler->Bind(&if_valueisnotzero); | |
| 3569 assembler->Return(assembler->BooleanConstant(true)); | |
| 3570 } | 3564 } |
| 3571 | 3565 |
| 3572 assembler->Bind(&if_valueisnotsmi); | 3566 assembler->Bind(&if_valueisnotsmi); |
| 3573 { | 3567 { |
| 3574 Label if_valueisstring(assembler), if_valueisheapnumber(assembler), | 3568 Label if_valueisstring(assembler), if_valueisnotstring(assembler), |
| 3575 if_valueisoddball(assembler), if_valueisother(assembler); | 3569 if_valueisheapnumber(assembler), if_valueisoddball(assembler), |
| 3570 if_valueisother(assembler); |
| 3576 | 3571 |
| 3577 // The {value} is a HeapObject, load its map. | 3572 // The {value} is a HeapObject, load its map. |
| 3578 Node* value_map = assembler->LoadMap(value); | 3573 Node* value_map = assembler->LoadMap(value); |
| 3579 | 3574 |
| 3580 // Load the {value}s instance type. | 3575 // Load the {value}s instance type. |
| 3581 Node* value_instance_type = assembler->Load( | 3576 Node* value_instance_type = assembler->Load( |
| 3582 MachineType::Uint8(), value_map, | 3577 MachineType::Uint8(), value_map, |
| 3583 assembler->IntPtrConstant(Map::kInstanceTypeOffset - kHeapObjectTag)); | 3578 assembler->IntPtrConstant(Map::kInstanceTypeOffset - kHeapObjectTag)); |
| 3584 | 3579 |
| 3585 // Dispatch based on the instance type; we distinguish all String instance | 3580 // Dispatch based on the instance type; we distinguish all String instance |
| 3586 // types, the HeapNumber type and the Oddball type. | 3581 // types, the HeapNumber type and the Oddball type. |
| 3587 size_t const kNumCases = FIRST_NONSTRING_TYPE + 2; | 3582 assembler->Branch(assembler->Int32LessThan( |
| 3583 value_instance_type, |
| 3584 assembler->Int32Constant(FIRST_NONSTRING_TYPE)), |
| 3585 &if_valueisstring, &if_valueisnotstring); |
| 3586 assembler->Bind(&if_valueisnotstring); |
| 3587 size_t const kNumCases = 2; |
| 3588 Label* case_labels[kNumCases]; | 3588 Label* case_labels[kNumCases]; |
| 3589 int32_t case_values[kNumCases]; | 3589 int32_t case_values[kNumCases]; |
| 3590 for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) { | 3590 case_labels[0] = &if_valueisheapnumber; |
| 3591 case_labels[i] = new Label(assembler); | 3591 case_values[0] = HEAP_NUMBER_TYPE; |
| 3592 case_values[i] = i; | 3592 case_labels[1] = &if_valueisoddball; |
| 3593 } | 3593 case_values[1] = ODDBALL_TYPE; |
| 3594 case_labels[FIRST_NONSTRING_TYPE + 0] = &if_valueisheapnumber; | |
| 3595 case_values[FIRST_NONSTRING_TYPE + 0] = HEAP_NUMBER_TYPE; | |
| 3596 case_labels[FIRST_NONSTRING_TYPE + 1] = &if_valueisoddball; | |
| 3597 case_values[FIRST_NONSTRING_TYPE + 1] = ODDBALL_TYPE; | |
| 3598 assembler->Switch(value_instance_type, &if_valueisother, case_values, | 3594 assembler->Switch(value_instance_type, &if_valueisother, case_values, |
| 3599 case_labels, arraysize(case_values)); | 3595 case_labels, arraysize(case_values)); |
| 3600 for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) { | |
| 3601 assembler->Bind(case_labels[i]); | |
| 3602 assembler->Goto(&if_valueisstring); | |
| 3603 delete case_labels[i]; | |
| 3604 } | |
| 3605 | 3596 |
| 3606 assembler->Bind(&if_valueisstring); | 3597 assembler->Bind(&if_valueisstring); |
| 3607 { | 3598 { |
| 3608 // Load the string length field of the {value}. | 3599 // Load the string length field of the {value}. |
| 3609 Node* value_length = | 3600 Node* value_length = |
| 3610 assembler->LoadObjectField(value, String::kLengthOffset); | 3601 assembler->LoadObjectField(value, String::kLengthOffset); |
| 3611 | 3602 |
| 3612 // Check if the {value} is the empty string. | 3603 // Check if the {value} is the empty string. |
| 3613 Label if_valueisempty(assembler), if_valueisnotempty(assembler); | |
| 3614 assembler->Branch( | 3604 assembler->Branch( |
| 3615 assembler->SmiEqual(value_length, assembler->SmiConstant(0)), | 3605 assembler->SmiEqual(value_length, assembler->SmiConstant(0)), |
| 3616 &if_valueisempty, &if_valueisnotempty); | 3606 &return_false, &return_true); |
| 3617 | |
| 3618 assembler->Bind(&if_valueisempty); | |
| 3619 assembler->Return(assembler->BooleanConstant(false)); | |
| 3620 | |
| 3621 assembler->Bind(&if_valueisnotempty); | |
| 3622 assembler->Return(assembler->BooleanConstant(true)); | |
| 3623 } | 3607 } |
| 3624 | 3608 |
| 3625 assembler->Bind(&if_valueisheapnumber); | 3609 assembler->Bind(&if_valueisheapnumber); |
| 3626 { | 3610 { |
| 3627 Node* value_value = assembler->Load( | 3611 Node* value_value = assembler->Load( |
| 3628 MachineType::Float64(), value, | 3612 MachineType::Float64(), value, |
| 3629 assembler->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag)); | 3613 assembler->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag)); |
| 3630 | 3614 |
| 3631 Label if_valueispositive(assembler), if_valueisnotpositive(assembler), | 3615 Label if_valueisnotpositive(assembler); |
| 3632 if_valueisnegative(assembler), if_valueisnanorzero(assembler); | |
| 3633 assembler->Branch(assembler->Float64LessThan( | 3616 assembler->Branch(assembler->Float64LessThan( |
| 3634 assembler->Float64Constant(0.0), value_value), | 3617 assembler->Float64Constant(0.0), value_value), |
| 3635 &if_valueispositive, &if_valueisnotpositive); | 3618 &return_true, &if_valueisnotpositive); |
| 3636 | |
| 3637 assembler->Bind(&if_valueispositive); | |
| 3638 assembler->Return(assembler->BooleanConstant(true)); | |
| 3639 | 3619 |
| 3640 assembler->Bind(&if_valueisnotpositive); | 3620 assembler->Bind(&if_valueisnotpositive); |
| 3641 assembler->Branch(assembler->Float64LessThan( | 3621 assembler->Branch(assembler->Float64LessThan( |
| 3642 value_value, assembler->Float64Constant(0.0)), | 3622 value_value, assembler->Float64Constant(0.0)), |
| 3643 &if_valueisnegative, &if_valueisnanorzero); | 3623 &return_true, &return_false); |
| 3644 | |
| 3645 assembler->Bind(&if_valueisnegative); | |
| 3646 assembler->Return(assembler->BooleanConstant(true)); | |
| 3647 | |
| 3648 assembler->Bind(&if_valueisnanorzero); | |
| 3649 assembler->Return(assembler->BooleanConstant(false)); | |
| 3650 } | 3624 } |
| 3651 | 3625 |
| 3652 assembler->Bind(&if_valueisoddball); | 3626 assembler->Bind(&if_valueisoddball); |
| 3653 { | 3627 { |
| 3654 // The {value} is an Oddball, and every Oddball knows its boolean value. | 3628 // The {value} is an Oddball, and every Oddball knows its boolean value. |
| 3655 Node* value_toboolean = | 3629 Node* value_toboolean = |
| 3656 assembler->LoadObjectField(value, Oddball::kToBooleanOffset); | 3630 assembler->LoadObjectField(value, Oddball::kToBooleanOffset); |
| 3657 assembler->Return(value_toboolean); | 3631 assembler->Return(value_toboolean); |
| 3658 } | 3632 } |
| 3659 | 3633 |
| 3660 assembler->Bind(&if_valueisother); | 3634 assembler->Bind(&if_valueisother); |
| 3661 { | 3635 { |
| 3662 Node* value_map_bitfield = assembler->Load( | 3636 Node* value_map_bitfield = assembler->Load( |
| 3663 MachineType::Uint8(), value_map, | 3637 MachineType::Uint8(), value_map, |
| 3664 assembler->IntPtrConstant(Map::kBitFieldOffset - kHeapObjectTag)); | 3638 assembler->IntPtrConstant(Map::kBitFieldOffset - kHeapObjectTag)); |
| 3665 Node* value_map_undetectable = assembler->Word32And( | 3639 Node* value_map_undetectable = assembler->Word32And( |
| 3666 value_map_bitfield, | 3640 value_map_bitfield, |
| 3667 assembler->Int32Constant(1 << Map::kIsUndetectable)); | 3641 assembler->Int32Constant(1 << Map::kIsUndetectable)); |
| 3668 | 3642 |
| 3669 // Check if the {value} is undetectable. | 3643 // Check if the {value} is undetectable. |
| 3670 Label if_valueisundetectable(assembler), | |
| 3671 if_valueisnotundetectable(assembler); | |
| 3672 assembler->Branch(assembler->Word32Equal(value_map_undetectable, | 3644 assembler->Branch(assembler->Word32Equal(value_map_undetectable, |
| 3673 assembler->Int32Constant(0)), | 3645 assembler->Int32Constant(0)), |
| 3674 &if_valueisnotundetectable, &if_valueisundetectable); | 3646 &return_true, &return_false); |
| 3675 | |
| 3676 assembler->Bind(&if_valueisundetectable); | |
| 3677 assembler->Return(assembler->BooleanConstant(false)); | |
| 3678 | |
| 3679 assembler->Bind(&if_valueisnotundetectable); | |
| 3680 assembler->Return(assembler->BooleanConstant(true)); | |
| 3681 } | 3647 } |
| 3682 } | 3648 } |
| 3649 assembler->Bind(&return_false); |
| 3650 assembler->Return(assembler->BooleanConstant(false)); |
| 3651 |
| 3652 assembler->Bind(&return_true); |
| 3653 assembler->Return(assembler->BooleanConstant(true)); |
| 3683 } | 3654 } |
| 3684 | 3655 |
| 3685 void ToIntegerStub::GenerateAssembly(CodeStubAssembler* assembler) const { | 3656 void ToIntegerStub::GenerateAssembly(CodeStubAssembler* assembler) const { |
| 3686 typedef CodeStubAssembler::Label Label; | 3657 typedef CodeStubAssembler::Label Label; |
| 3687 typedef compiler::Node Node; | 3658 typedef compiler::Node Node; |
| 3688 typedef CodeStubAssembler::Variable Variable; | 3659 typedef CodeStubAssembler::Variable Variable; |
| 3689 | 3660 |
| 3690 Node* context = assembler->Parameter(1); | 3661 Node* context = assembler->Parameter(1); |
| 3691 | 3662 |
| 3692 // We might need to loop once for ToNumber conversion. | 3663 // We might need to loop once for ToNumber conversion. |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4275 if (type->Is(Type::UntaggedPointer())) { | 4246 if (type->Is(Type::UntaggedPointer())) { |
| 4276 return Representation::External(); | 4247 return Representation::External(); |
| 4277 } | 4248 } |
| 4278 | 4249 |
| 4279 DCHECK(!type->Is(Type::Untagged())); | 4250 DCHECK(!type->Is(Type::Untagged())); |
| 4280 return Representation::Tagged(); | 4251 return Representation::Tagged(); |
| 4281 } | 4252 } |
| 4282 | 4253 |
| 4283 } // namespace internal | 4254 } // namespace internal |
| 4284 } // namespace v8 | 4255 } // namespace v8 |
| OLD | NEW |