| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1204 } | 1204 } |
| 1205 | 1205 |
| 1206 | 1206 |
| 1207 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { | 1207 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { |
| 1208 Register result = ToRegister(instr->result()); | 1208 Register result = ToRegister(instr->result()); |
| 1209 Register array = ToRegister(instr->InputAt(0)); | 1209 Register array = ToRegister(instr->InputAt(0)); |
| 1210 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); | 1210 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); |
| 1211 } | 1211 } |
| 1212 | 1212 |
| 1213 | 1213 |
| 1214 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { | 1214 void LCodeGen::DoFixedArrayBaseLength( |
| 1215 LFixedArrayBaseLength* instr) { |
| 1215 Register result = ToRegister(instr->result()); | 1216 Register result = ToRegister(instr->result()); |
| 1216 Register array = ToRegister(instr->InputAt(0)); | 1217 Register array = ToRegister(instr->InputAt(0)); |
| 1217 __ mov(result, FieldOperand(array, FixedArray::kLengthOffset)); | 1218 __ mov(result, FieldOperand(array, FixedArrayBase::kLengthOffset)); |
| 1218 } | |
| 1219 | |
| 1220 | |
| 1221 void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) { | |
| 1222 Register result = ToRegister(instr->result()); | |
| 1223 Register array = ToRegister(instr->InputAt(0)); | |
| 1224 __ mov(result, FieldOperand(array, ExternalArray::kLengthOffset)); | |
| 1225 } | 1219 } |
| 1226 | 1220 |
| 1227 | 1221 |
| 1228 void LCodeGen::DoElementsKind(LElementsKind* instr) { | 1222 void LCodeGen::DoElementsKind(LElementsKind* instr) { |
| 1229 Register result = ToRegister(instr->result()); | 1223 Register result = ToRegister(instr->result()); |
| 1230 Register input = ToRegister(instr->InputAt(0)); | 1224 Register input = ToRegister(instr->InputAt(0)); |
| 1231 | 1225 |
| 1232 // Load map into |result|. | 1226 // Load map into |result|. |
| 1233 __ mov(result, FieldOperand(input, HeapObject::kMapOffset)); | 1227 __ mov(result, FieldOperand(input, HeapObject::kMapOffset)); |
| 1234 // Load the map's "bit field 2" into |result|. We only need the first byte, | 1228 // Load the map's "bit field 2" into |result|. We only need the first byte, |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1399 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1406 | 1400 |
| 1407 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); | 1401 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); |
| 1408 // Avoid deopts in the case where we've never executed this path before. | 1402 // Avoid deopts in the case where we've never executed this path before. |
| 1409 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); | 1403 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); |
| 1410 | 1404 |
| 1411 if (expected.Contains(ToBooleanStub::UNDEFINED)) { | 1405 if (expected.Contains(ToBooleanStub::UNDEFINED)) { |
| 1412 // undefined -> false. | 1406 // undefined -> false. |
| 1413 __ cmp(reg, factory()->undefined_value()); | 1407 __ cmp(reg, factory()->undefined_value()); |
| 1414 __ j(equal, false_label); | 1408 __ j(equal, false_label); |
| 1415 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
| 1416 // We've seen undefined for the first time -> deopt. | |
| 1417 __ cmp(reg, factory()->undefined_value()); | |
| 1418 DeoptimizeIf(equal, instr->environment()); | |
| 1419 } | 1409 } |
| 1420 | |
| 1421 if (expected.Contains(ToBooleanStub::BOOLEAN)) { | 1410 if (expected.Contains(ToBooleanStub::BOOLEAN)) { |
| 1422 // true -> true. | 1411 // true -> true. |
| 1423 __ cmp(reg, factory()->true_value()); | 1412 __ cmp(reg, factory()->true_value()); |
| 1424 __ j(equal, true_label); | 1413 __ j(equal, true_label); |
| 1425 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
| 1426 // We've seen a boolean for the first time -> deopt. | |
| 1427 __ cmp(reg, factory()->true_value()); | |
| 1428 DeoptimizeIf(equal, instr->environment()); | |
| 1429 } | |
| 1430 | |
| 1431 if (expected.Contains(ToBooleanStub::BOOLEAN)) { | |
| 1432 // false -> false. | 1414 // false -> false. |
| 1433 __ cmp(reg, factory()->false_value()); | 1415 __ cmp(reg, factory()->false_value()); |
| 1434 __ j(equal, false_label); | 1416 __ j(equal, false_label); |
| 1435 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
| 1436 // We've seen a boolean for the first time -> deopt. | |
| 1437 __ cmp(reg, factory()->false_value()); | |
| 1438 DeoptimizeIf(equal, instr->environment()); | |
| 1439 } | 1417 } |
| 1440 | |
| 1441 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { | 1418 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { |
| 1442 // 'null' -> false. | 1419 // 'null' -> false. |
| 1443 __ cmp(reg, factory()->null_value()); | 1420 __ cmp(reg, factory()->null_value()); |
| 1444 __ j(equal, false_label); | 1421 __ j(equal, false_label); |
| 1445 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
| 1446 // We've seen null for the first time -> deopt. | |
| 1447 __ cmp(reg, factory()->null_value()); | |
| 1448 DeoptimizeIf(equal, instr->environment()); | |
| 1449 } | 1422 } |
| 1450 | 1423 |
| 1451 if (expected.Contains(ToBooleanStub::SMI)) { | 1424 if (expected.Contains(ToBooleanStub::SMI)) { |
| 1452 // Smis: 0 -> false, all other -> true. | 1425 // Smis: 0 -> false, all other -> true. |
| 1453 __ test(reg, Operand(reg)); | 1426 __ test(reg, Operand(reg)); |
| 1454 __ j(equal, false_label); | 1427 __ j(equal, false_label); |
| 1455 __ JumpIfSmi(reg, true_label); | 1428 __ JumpIfSmi(reg, true_label); |
| 1456 } else if (expected.NeedsMap()) { | 1429 } else if (expected.NeedsMap()) { |
| 1457 // If we need a map later and have a Smi -> deopt. | 1430 // If we need a map later and have a Smi -> deopt. |
| 1458 __ test(reg, Immediate(kSmiTagMask)); | 1431 __ test(reg, Immediate(kSmiTagMask)); |
| 1459 DeoptimizeIf(zero, instr->environment()); | 1432 DeoptimizeIf(zero, instr->environment()); |
| 1460 } | 1433 } |
| 1461 | 1434 |
| 1462 Register map = no_reg; | 1435 Register map = no_reg; // Keep the compiler happy. |
| 1463 if (expected.NeedsMap()) { | 1436 if (expected.NeedsMap()) { |
| 1464 map = ToRegister(instr->TempAt(0)); | 1437 map = ToRegister(instr->TempAt(0)); |
| 1465 ASSERT(!map.is(reg)); | 1438 ASSERT(!map.is(reg)); |
| 1466 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); | 1439 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); |
| 1467 // Everything with a map could be undetectable, so check this now. | 1440 |
| 1468 __ test_b(FieldOperand(map, Map::kBitFieldOffset), | 1441 if (expected.CanBeUndetectable()) { |
| 1469 1 << Map::kIsUndetectable); | 1442 // Undetectable -> false. |
| 1470 // Undetectable -> false. | 1443 __ test_b(FieldOperand(map, Map::kBitFieldOffset), |
| 1471 __ j(not_zero, false_label); | 1444 1 << Map::kIsUndetectable); |
| 1445 __ j(not_zero, false_label); |
| 1446 } |
| 1472 } | 1447 } |
| 1473 | 1448 |
| 1474 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 1449 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { |
| 1475 // spec object -> true. | 1450 // spec object -> true. |
| 1476 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); | 1451 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); |
| 1477 __ j(above_equal, true_label); | 1452 __ j(above_equal, true_label); |
| 1478 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
| 1479 // We've seen a spec object for the first time -> deopt. | |
| 1480 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); | |
| 1481 DeoptimizeIf(above_equal, instr->environment()); | |
| 1482 } | 1453 } |
| 1483 | 1454 |
| 1484 if (expected.Contains(ToBooleanStub::STRING)) { | 1455 if (expected.Contains(ToBooleanStub::STRING)) { |
| 1485 // String value -> false iff empty. | 1456 // String value -> false iff empty. |
| 1486 Label not_string; | 1457 Label not_string; |
| 1487 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); | 1458 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); |
| 1488 __ j(above_equal, ¬_string, Label::kNear); | 1459 __ j(above_equal, ¬_string, Label::kNear); |
| 1489 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); | 1460 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); |
| 1490 __ j(not_zero, true_label); | 1461 __ j(not_zero, true_label); |
| 1491 __ jmp(false_label); | 1462 __ jmp(false_label); |
| 1492 __ bind(¬_string); | 1463 __ bind(¬_string); |
| 1493 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
| 1494 // We've seen a string for the first time -> deopt | |
| 1495 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); | |
| 1496 DeoptimizeIf(below, instr->environment()); | |
| 1497 } | 1464 } |
| 1498 | 1465 |
| 1499 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 1466 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
| 1500 // heap number -> false iff +0, -0, or NaN. | 1467 // heap number -> false iff +0, -0, or NaN. |
| 1501 Label not_heap_number; | 1468 Label not_heap_number; |
| 1502 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 1469 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 1503 factory()->heap_number_map()); | 1470 factory()->heap_number_map()); |
| 1504 __ j(not_equal, ¬_heap_number, Label::kNear); | 1471 __ j(not_equal, ¬_heap_number, Label::kNear); |
| 1505 __ fldz(); | 1472 __ fldz(); |
| 1506 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 1473 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); |
| 1507 __ FCmp(); | 1474 __ FCmp(); |
| 1508 __ j(zero, false_label); | 1475 __ j(zero, false_label); |
| 1509 __ jmp(true_label); | 1476 __ jmp(true_label); |
| 1510 __ bind(¬_heap_number); | 1477 __ bind(¬_heap_number); |
| 1511 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
| 1512 // We've seen a heap number for the first time -> deopt. | |
| 1513 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | |
| 1514 factory()->heap_number_map()); | |
| 1515 DeoptimizeIf(equal, instr->environment()); | |
| 1516 } | 1478 } |
| 1517 | 1479 |
| 1518 if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | 1480 // We've seen something for the first time -> deopt. |
| 1519 // internal objects -> true | 1481 DeoptimizeIf(no_condition, instr->environment()); |
| 1520 __ jmp(true_label); | |
| 1521 } else { | |
| 1522 // We've seen something for the first time -> deopt. | |
| 1523 DeoptimizeIf(no_condition, instr->environment()); | |
| 1524 } | |
| 1525 } | 1482 } |
| 1526 } | 1483 } |
| 1527 } | 1484 } |
| 1528 | 1485 |
| 1529 | 1486 |
| 1530 void LCodeGen::EmitGoto(int block) { | 1487 void LCodeGen::EmitGoto(int block) { |
| 1531 block = chunk_->LookupDestination(block); | 1488 block = chunk_->LookupDestination(block); |
| 1532 int next_block = GetNextEmittedBlock(current_block_); | 1489 int next_block = GetNextEmittedBlock(current_block_); |
| 1533 if (block != next_block) { | 1490 if (block != next_block) { |
| 1534 __ jmp(chunk_->GetAssemblyLabel(block)); | 1491 __ jmp(chunk_->GetAssemblyLabel(block)); |
| (...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2749 EmitIntegerMathAbs(instr); | 2706 EmitIntegerMathAbs(instr); |
| 2750 __ bind(deferred->exit()); | 2707 __ bind(deferred->exit()); |
| 2751 } | 2708 } |
| 2752 } | 2709 } |
| 2753 | 2710 |
| 2754 | 2711 |
| 2755 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 2712 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
| 2756 XMMRegister xmm_scratch = xmm0; | 2713 XMMRegister xmm_scratch = xmm0; |
| 2757 Register output_reg = ToRegister(instr->result()); | 2714 Register output_reg = ToRegister(instr->result()); |
| 2758 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 2715 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 2759 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. | |
| 2760 __ ucomisd(input_reg, xmm_scratch); | |
| 2761 | 2716 |
| 2762 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 2717 if (CpuFeatures::IsSupported(SSE4_1)) { |
| 2763 DeoptimizeIf(below_equal, instr->environment()); | 2718 CpuFeatures::Scope scope(SSE4_1); |
| 2719 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 2720 // Deoptimize on negative zero. |
| 2721 Label non_zero; |
| 2722 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. |
| 2723 __ ucomisd(input_reg, xmm_scratch); |
| 2724 __ j(not_equal, &non_zero, Label::kNear); |
| 2725 __ movmskpd(output_reg, input_reg); |
| 2726 __ test(output_reg, Immediate(1)); |
| 2727 DeoptimizeIf(not_zero, instr->environment()); |
| 2728 __ bind(&non_zero); |
| 2729 } |
| 2730 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); |
| 2731 __ cvttsd2si(output_reg, Operand(xmm_scratch)); |
| 2732 // Overflow is signalled with minint. |
| 2733 __ cmp(output_reg, 0x80000000u); |
| 2734 DeoptimizeIf(equal, instr->environment()); |
| 2764 } else { | 2735 } else { |
| 2736 Label done; |
| 2737 // Deoptimize on negative numbers. |
| 2738 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. |
| 2739 __ ucomisd(input_reg, xmm_scratch); |
| 2765 DeoptimizeIf(below, instr->environment()); | 2740 DeoptimizeIf(below, instr->environment()); |
| 2741 |
| 2742 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 2743 // Check for negative zero. |
| 2744 Label positive_sign; |
| 2745 __ j(above, &positive_sign, Label::kNear); |
| 2746 __ movmskpd(output_reg, input_reg); |
| 2747 __ test(output_reg, Immediate(1)); |
| 2748 DeoptimizeIf(not_zero, instr->environment()); |
| 2749 __ Set(output_reg, Immediate(0)); |
| 2750 __ jmp(&done, Label::kNear); |
| 2751 __ bind(&positive_sign); |
| 2752 } |
| 2753 |
| 2754 // Use truncating instruction (OK because input is positive). |
| 2755 __ cvttsd2si(output_reg, Operand(input_reg)); |
| 2756 |
| 2757 // Overflow is signalled with minint. |
| 2758 __ cmp(output_reg, 0x80000000u); |
| 2759 DeoptimizeIf(equal, instr->environment()); |
| 2760 __ bind(&done); |
| 2766 } | 2761 } |
| 2767 | |
| 2768 // Use truncating instruction (OK because input is positive). | |
| 2769 __ cvttsd2si(output_reg, Operand(input_reg)); | |
| 2770 | |
| 2771 // Overflow is signalled with minint. | |
| 2772 __ cmp(output_reg, 0x80000000u); | |
| 2773 DeoptimizeIf(equal, instr->environment()); | |
| 2774 } | 2762 } |
| 2775 | 2763 |
| 2776 | |
| 2777 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 2764 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
| 2778 XMMRegister xmm_scratch = xmm0; | 2765 XMMRegister xmm_scratch = xmm0; |
| 2779 Register output_reg = ToRegister(instr->result()); | 2766 Register output_reg = ToRegister(instr->result()); |
| 2780 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 2767 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 2781 | 2768 |
| 2782 Label below_half, done; | 2769 Label below_half, done; |
| 2783 // xmm_scratch = 0.5 | 2770 // xmm_scratch = 0.5 |
| 2784 ExternalReference one_half = ExternalReference::address_of_one_half(); | 2771 ExternalReference one_half = ExternalReference::address_of_one_half(); |
| 2785 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); | 2772 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); |
| 2786 | |
| 2787 __ ucomisd(xmm_scratch, input_reg); | 2773 __ ucomisd(xmm_scratch, input_reg); |
| 2788 __ j(above, &below_half); | 2774 __ j(above, &below_half); |
| 2789 // input = input + 0.5 | 2775 // input = input + 0.5 |
| 2790 __ addsd(input_reg, xmm_scratch); | 2776 __ addsd(input_reg, xmm_scratch); |
| 2791 | 2777 |
| 2792 | |
| 2793 // Compute Math.floor(value + 0.5). | 2778 // Compute Math.floor(value + 0.5). |
| 2794 // Use truncating instruction (OK because input is positive). | 2779 // Use truncating instruction (OK because input is positive). |
| 2795 __ cvttsd2si(output_reg, Operand(input_reg)); | 2780 __ cvttsd2si(output_reg, Operand(input_reg)); |
| 2796 | 2781 |
| 2797 // Overflow is signalled with minint. | 2782 // Overflow is signalled with minint. |
| 2798 __ cmp(output_reg, 0x80000000u); | 2783 __ cmp(output_reg, 0x80000000u); |
| 2799 DeoptimizeIf(equal, instr->environment()); | 2784 DeoptimizeIf(equal, instr->environment()); |
| 2800 __ jmp(&done); | 2785 __ jmp(&done); |
| 2801 | 2786 |
| 2802 __ bind(&below_half); | 2787 __ bind(&below_half); |
| (...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4193 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 4178 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 4194 1 << Map::kIsUndetectable); | 4179 1 << Map::kIsUndetectable); |
| 4195 final_branch_condition = zero; | 4180 final_branch_condition = zero; |
| 4196 | 4181 |
| 4197 } else if (type_name->Equals(heap()->boolean_symbol())) { | 4182 } else if (type_name->Equals(heap()->boolean_symbol())) { |
| 4198 __ cmp(input, factory()->true_value()); | 4183 __ cmp(input, factory()->true_value()); |
| 4199 __ j(equal, true_label); | 4184 __ j(equal, true_label); |
| 4200 __ cmp(input, factory()->false_value()); | 4185 __ cmp(input, factory()->false_value()); |
| 4201 final_branch_condition = equal; | 4186 final_branch_condition = equal; |
| 4202 | 4187 |
| 4188 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_symbol())) { |
| 4189 __ cmp(input, factory()->null_value()); |
| 4190 final_branch_condition = equal; |
| 4191 |
| 4203 } else if (type_name->Equals(heap()->undefined_symbol())) { | 4192 } else if (type_name->Equals(heap()->undefined_symbol())) { |
| 4204 __ cmp(input, factory()->undefined_value()); | 4193 __ cmp(input, factory()->undefined_value()); |
| 4205 __ j(equal, true_label); | 4194 __ j(equal, true_label); |
| 4206 __ JumpIfSmi(input, false_label); | 4195 __ JumpIfSmi(input, false_label); |
| 4207 // Check for undetectable objects => true. | 4196 // Check for undetectable objects => true. |
| 4208 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); | 4197 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); |
| 4209 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 4198 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 4210 1 << Map::kIsUndetectable); | 4199 1 << Map::kIsUndetectable); |
| 4211 final_branch_condition = not_zero; | 4200 final_branch_condition = not_zero; |
| 4212 | 4201 |
| 4213 } else if (type_name->Equals(heap()->function_symbol())) { | 4202 } else if (type_name->Equals(heap()->function_symbol())) { |
| 4214 STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE); | 4203 STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE); |
| 4215 __ JumpIfSmi(input, false_label); | 4204 __ JumpIfSmi(input, false_label); |
| 4216 __ CmpObjectType(input, FIRST_CALLABLE_SPEC_OBJECT_TYPE, input); | 4205 __ CmpObjectType(input, FIRST_CALLABLE_SPEC_OBJECT_TYPE, input); |
| 4217 final_branch_condition = above_equal; | 4206 final_branch_condition = above_equal; |
| 4218 | 4207 |
| 4219 } else if (type_name->Equals(heap()->object_symbol())) { | 4208 } else if (type_name->Equals(heap()->object_symbol())) { |
| 4220 __ JumpIfSmi(input, false_label); | 4209 __ JumpIfSmi(input, false_label); |
| 4221 __ cmp(input, factory()->null_value()); | 4210 if (!FLAG_harmony_typeof) { |
| 4222 __ j(equal, true_label); | 4211 __ cmp(input, factory()->null_value()); |
| 4212 __ j(equal, true_label); |
| 4213 } |
| 4223 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); | 4214 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); |
| 4224 __ j(below, false_label); | 4215 __ j(below, false_label); |
| 4225 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4216 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
| 4226 __ j(above, false_label); | 4217 __ j(above, false_label); |
| 4227 // Check for undetectable objects => false. | 4218 // Check for undetectable objects => false. |
| 4228 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 4219 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 4229 1 << Map::kIsUndetectable); | 4220 1 << Map::kIsUndetectable); |
| 4230 final_branch_condition = zero; | 4221 final_branch_condition = zero; |
| 4231 | 4222 |
| 4232 } else { | 4223 } else { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4399 env->deoptimization_index()); | 4390 env->deoptimization_index()); |
| 4400 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4391 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
| 4401 } | 4392 } |
| 4402 | 4393 |
| 4403 | 4394 |
| 4404 #undef __ | 4395 #undef __ |
| 4405 | 4396 |
| 4406 } } // namespace v8::internal | 4397 } } // namespace v8::internal |
| 4407 | 4398 |
| 4408 #endif // V8_TARGET_ARCH_IA32 | 4399 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |