OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. | 1483 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. |
1484 if (cc == greater || cc == less_equal) { | 1484 if (cc == greater || cc == less_equal) { |
1485 cc = ReverseCondition(cc); | 1485 cc = ReverseCondition(cc); |
1486 __ pop(edx); | 1486 __ pop(edx); |
1487 __ pop(eax); | 1487 __ pop(eax); |
1488 } else { | 1488 } else { |
1489 __ pop(eax); | 1489 __ pop(eax); |
1490 __ pop(edx); | 1490 __ pop(edx); |
1491 } | 1491 } |
1492 | 1492 |
| 1493 // Check for the smi case. |
1493 Label is_smi, done; | 1494 Label is_smi, done; |
1494 CompareStub stub(cc, strict); | |
1495 | |
1496 __ mov(ecx, Operand(eax)); | 1495 __ mov(ecx, Operand(eax)); |
1497 __ or_(ecx, Operand(edx)); | 1496 __ or_(ecx, Operand(edx)); |
1498 __ test(ecx, Immediate(kSmiTagMask)); | 1497 __ test(ecx, Immediate(kSmiTagMask)); |
1499 __ j(zero, &is_smi, taken); | 1498 __ j(zero, &is_smi, taken); |
1500 | 1499 |
1501 // When non-smi, call out to the compare stub. "parameters" setup by | 1500 // When non-smi, call out to the compare stub. "parameters" setup by |
1502 // calling code in edx and eax and "result" is returned in the flags. | 1501 // calling code in edx and eax and "result" is returned in the flags. |
| 1502 CompareStub stub(cc, strict); |
1503 __ CallStub(&stub); | 1503 __ CallStub(&stub); |
1504 __ cmp(eax, 0); | 1504 if (cc == equal) { |
| 1505 __ test(eax, Operand(eax)); |
| 1506 } else { |
| 1507 __ cmp(eax, 0); |
| 1508 } |
1505 __ jmp(&done); | 1509 __ jmp(&done); |
1506 | 1510 |
1507 // Test smi equality by pointer comparison. | 1511 // Test smi equality by pointer comparison. |
1508 __ bind(&is_smi); | 1512 __ bind(&is_smi); |
1509 __ cmp(edx, Operand(eax)); | 1513 __ cmp(edx, Operand(eax)); |
1510 // Fall through to |done|. | 1514 // Fall through to |done|. |
1511 | 1515 |
1512 __ bind(&done); | 1516 __ bind(&done); |
1513 cc_reg_ = cc; | 1517 cc_reg_ = cc; |
1514 } | 1518 } |
(...skipping 3324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4839 __ mov(Operand(esp, 2 * kPointerSize), edx); | 4843 __ mov(Operand(esp, 2 * kPointerSize), edx); |
4840 | 4844 |
4841 // Do the runtime call to allocate the arguments object. | 4845 // Do the runtime call to allocate the arguments object. |
4842 __ bind(&runtime); | 4846 __ bind(&runtime); |
4843 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3); | 4847 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3); |
4844 } | 4848 } |
4845 | 4849 |
4846 | 4850 |
4847 void CompareStub::Generate(MacroAssembler* masm) { | 4851 void CompareStub::Generate(MacroAssembler* masm) { |
4848 Label call_builtin, done; | 4852 Label call_builtin, done; |
| 4853 |
| 4854 // If we're doing a strict equality comparison, we generate code |
| 4855 // to do fast comparison for objects and oddballs. Numbers and |
| 4856 // strings still go through the usual slow-case code. |
| 4857 if (strict_) { |
| 4858 Label slow; |
| 4859 __ test(eax, Immediate(kSmiTagMask)); |
| 4860 __ j(zero, &slow); |
| 4861 |
| 4862 // Get the type of the first operand. |
| 4863 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 4864 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| 4865 |
| 4866 // If the first object is an object, we do pointer comparison. |
| 4867 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); |
| 4868 Label non_object; |
| 4869 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); |
| 4870 __ j(less, &non_object); |
| 4871 __ sub(eax, Operand(edx)); |
| 4872 __ ret(0); |
| 4873 |
| 4874 // Check for oddballs: true, false, null, undefined. |
| 4875 __ bind(&non_object); |
| 4876 __ cmp(ecx, ODDBALL_TYPE); |
| 4877 __ j(not_equal, &slow); |
| 4878 |
| 4879 // If the oddball isn't undefined, we do pointer comparison. For |
| 4880 // the undefined value, we have to be careful and check for |
| 4881 // 'undetectable' objects too. |
| 4882 Label undefined; |
| 4883 __ cmp(Operand(eax), Immediate(Factory::undefined_value())); |
| 4884 __ j(equal, &undefined); |
| 4885 __ sub(eax, Operand(edx)); |
| 4886 __ ret(0); |
| 4887 |
| 4888 // Undefined case: If the other operand isn't undefined too, we |
| 4889 // have to check if it's 'undetectable'. |
| 4890 Label check_undetectable; |
| 4891 __ bind(&undefined); |
| 4892 __ cmp(Operand(edx), Immediate(Factory::undefined_value())); |
| 4893 __ j(not_equal, &check_undetectable); |
| 4894 __ Set(eax, Immediate(0)); |
| 4895 __ ret(0); |
| 4896 |
| 4897 // Check for undetectability of the other operand. |
| 4898 Label not_strictly_equal; |
| 4899 __ bind(&check_undetectable); |
| 4900 __ test(edx, Immediate(kSmiTagMask)); |
| 4901 __ j(zero, ¬_strictly_equal); |
| 4902 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 4903 __ movzx_b(ecx, FieldOperand(ecx, Map::kBitFieldOffset)); |
| 4904 __ and_(ecx, 1 << Map::kIsUndetectable); |
| 4905 __ cmp(ecx, 1 << Map::kIsUndetectable); |
| 4906 __ j(not_equal, ¬_strictly_equal); |
| 4907 __ Set(eax, Immediate(0)); |
| 4908 __ ret(0); |
| 4909 |
| 4910 // No cigar: Objects aren't strictly equal. Register eax contains |
| 4911 // a non-smi value so it can't be 0. Just return. |
| 4912 ASSERT(kHeapTag != 0); |
| 4913 __ bind(¬_strictly_equal); |
| 4914 __ ret(0); |
| 4915 |
| 4916 // Fall through to the general case. |
| 4917 __ bind(&slow); |
| 4918 } |
| 4919 |
4849 // Save the return address (and get it off the stack). | 4920 // Save the return address (and get it off the stack). |
4850 __ pop(ecx); | 4921 __ pop(ecx); |
4851 | 4922 |
4852 // Push arguments. | 4923 // Push arguments. |
4853 __ push(eax); | 4924 __ push(eax); |
4854 __ push(edx); | 4925 __ push(edx); |
4855 __ push(ecx); | 4926 __ push(ecx); |
4856 | 4927 |
4857 // Inlined floating point compare. | 4928 // Inlined floating point compare. |
4858 // Call builtin if operands are not floating point or smi. | 4929 // Call builtin if operands are not floating point or smi. |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5354 bool is_eval) { | 5425 bool is_eval) { |
5355 Handle<Code> code = Ia32CodeGenerator::MakeCode(fun, script, is_eval); | 5426 Handle<Code> code = Ia32CodeGenerator::MakeCode(fun, script, is_eval); |
5356 if (!code.is_null()) { | 5427 if (!code.is_null()) { |
5357 Counters::total_compiled_code_size.Increment(code->instruction_size()); | 5428 Counters::total_compiled_code_size.Increment(code->instruction_size()); |
5358 } | 5429 } |
5359 return code; | 5430 return code; |
5360 } | 5431 } |
5361 | 5432 |
5362 | 5433 |
5363 } } // namespace v8::internal | 5434 } } // namespace v8::internal |
OLD | NEW |