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 |