| Index: src/x64/code-stubs-x64.cc
|
| ===================================================================
|
| --- src/x64/code-stubs-x64.cc (revision 8353)
|
| +++ src/x64/code-stubs-x64.cc (working copy)
|
| @@ -231,8 +231,11 @@
|
| }
|
|
|
|
|
| +// The stub returns zero for false, and a non-zero value for true.
|
| void ToBooleanStub::Generate(MacroAssembler* masm) {
|
| Label false_result, true_result, not_string;
|
| + const Register map = rdx;
|
| +
|
| __ movq(rax, Operand(rsp, 1 * kPointerSize));
|
|
|
| // undefined -> false
|
| @@ -250,48 +253,45 @@
|
| __ j(equal, &false_result);
|
| __ JumpIfSmi(rax, &true_result);
|
|
|
| - // 'null' => false.
|
| + // 'null' -> false.
|
| __ CompareRoot(rax, Heap::kNullValueRootIndex);
|
| __ j(equal, &false_result, Label::kNear);
|
|
|
| - // Get the map and type of the heap object.
|
| - // We don't use CmpObjectType because we manipulate the type field.
|
| - __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
|
| - __ movzxbq(rcx, FieldOperand(rdx, Map::kInstanceTypeOffset));
|
| + // Get the map of the heap object.
|
| + __ movq(map, FieldOperand(rax, HeapObject::kMapOffset));
|
|
|
| - // Undetectable => false.
|
| - __ movzxbq(rbx, FieldOperand(rdx, Map::kBitFieldOffset));
|
| - __ and_(rbx, Immediate(1 << Map::kIsUndetectable));
|
| + // Undetectable -> false.
|
| + __ testb(FieldOperand(map, Map::kBitFieldOffset),
|
| + Immediate(1 << Map::kIsUndetectable));
|
| __ j(not_zero, &false_result, Label::kNear);
|
|
|
| - // JavaScript object => true.
|
| - __ cmpq(rcx, Immediate(FIRST_SPEC_OBJECT_TYPE));
|
| + // JavaScript object -> true.
|
| + __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
|
| __ j(above_equal, &true_result, Label::kNear);
|
|
|
| - // String value => false iff empty.
|
| - __ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE));
|
| + // String value -> false iff empty.
|
| + __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
|
| __ j(above_equal, ¬_string, Label::kNear);
|
| - __ movq(rdx, FieldOperand(rax, String::kLengthOffset));
|
| - __ SmiTest(rdx);
|
| + __ cmpq(FieldOperand(rax, String::kLengthOffset), Immediate(0));
|
| __ j(zero, &false_result, Label::kNear);
|
| __ jmp(&true_result, Label::kNear);
|
|
|
| __ bind(¬_string);
|
| - __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
|
| + // HeapNumber -> false iff +0, -0, or NaN.
|
| + // These three cases set the zero flag when compared to zero using ucomisd.
|
| + __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
|
| __ j(not_equal, &true_result, Label::kNear);
|
| - // HeapNumber => false iff +0, -0, or NaN.
|
| - // These three cases set the zero flag when compared to zero using ucomisd.
|
| __ xorps(xmm0, xmm0);
|
| __ ucomisd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
|
| __ j(zero, &false_result, Label::kNear);
|
| // Fall through to |true_result|.
|
|
|
| - // Return 1/0 for true/false in rax.
|
| + // Return 1/0 for true/false in tos_.
|
| __ bind(&true_result);
|
| - __ Set(rax, 1);
|
| + __ Set(tos_, 1);
|
| __ ret(1 * kPointerSize);
|
| __ bind(&false_result);
|
| - __ Set(rax, 0);
|
| + __ Set(tos_, 0);
|
| __ ret(1 * kPointerSize);
|
| }
|
|
|
|
|