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 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 } | 1371 } |
1372 | 1372 |
1373 | 1373 |
1374 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { | 1374 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { |
1375 Register result = ToRegister(instr->result()); | 1375 Register result = ToRegister(instr->result()); |
1376 Register array = ToRegister(instr->InputAt(0)); | 1376 Register array = ToRegister(instr->InputAt(0)); |
1377 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset)); | 1377 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset)); |
1378 } | 1378 } |
1379 | 1379 |
1380 | 1380 |
1381 void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) { | 1381 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { |
1382 Register result = ToRegister(instr->result()); | 1382 Register result = ToRegister(instr->result()); |
1383 Register array = ToRegister(instr->InputAt(0)); | 1383 Register array = ToRegister(instr->InputAt(0)); |
1384 __ ldr(result, FieldMemOperand(array, ExternalArray::kLengthOffset)); | 1384 __ ldr(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset)); |
1385 } | |
1386 | |
1387 | |
1388 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { | |
1389 Register result = ToRegister(instr->result()); | |
1390 Register array = ToRegister(instr->InputAt(0)); | |
1391 __ ldr(result, FieldMemOperand(array, FixedArray::kLengthOffset)); | |
1392 } | 1385 } |
1393 | 1386 |
1394 | 1387 |
1395 void LCodeGen::DoElementsKind(LElementsKind* instr) { | 1388 void LCodeGen::DoElementsKind(LElementsKind* instr) { |
1396 Register result = ToRegister(instr->result()); | 1389 Register result = ToRegister(instr->result()); |
1397 Register input = ToRegister(instr->InputAt(0)); | 1390 Register input = ToRegister(instr->InputAt(0)); |
1398 | 1391 |
1399 // Load map into |result|. | 1392 // Load map into |result|. |
1400 __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset)); | 1393 __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset)); |
1401 // Load the map's "bit field 2" into |result|. We only need the first byte, | 1394 // Load the map's "bit field 2" into |result|. We only need the first byte, |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1569 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
1577 | 1570 |
1578 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); | 1571 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); |
1579 // Avoid deopts in the case where we've never executed this path before. | 1572 // Avoid deopts in the case where we've never executed this path before. |
1580 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); | 1573 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); |
1581 | 1574 |
1582 if (expected.Contains(ToBooleanStub::UNDEFINED)) { | 1575 if (expected.Contains(ToBooleanStub::UNDEFINED)) { |
1583 // undefined -> false. | 1576 // undefined -> false. |
1584 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); | 1577 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); |
1585 __ b(eq, false_label); | 1578 __ b(eq, false_label); |
1586 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
1587 // We've seen undefined for the first time -> deopt. | |
1588 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | |
1589 DeoptimizeIf(eq, instr->environment()); | |
1590 } | 1579 } |
1591 | |
1592 if (expected.Contains(ToBooleanStub::BOOLEAN)) { | 1580 if (expected.Contains(ToBooleanStub::BOOLEAN)) { |
1593 // Boolean -> its value. | 1581 // Boolean -> its value. |
1594 __ CompareRoot(reg, Heap::kTrueValueRootIndex); | 1582 __ CompareRoot(reg, Heap::kTrueValueRootIndex); |
1595 __ b(eq, true_label); | 1583 __ b(eq, true_label); |
1596 __ CompareRoot(reg, Heap::kFalseValueRootIndex); | 1584 __ CompareRoot(reg, Heap::kFalseValueRootIndex); |
1597 __ b(eq, false_label); | 1585 __ b(eq, false_label); |
1598 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
1599 // We've seen a boolean for the first time -> deopt. | |
1600 __ CompareRoot(reg, Heap::kTrueValueRootIndex); | |
1601 DeoptimizeIf(eq, instr->environment()); | |
1602 __ CompareRoot(reg, Heap::kFalseValueRootIndex); | |
1603 DeoptimizeIf(eq, instr->environment()); | |
1604 } | 1586 } |
1605 | |
1606 #if 0 | |
1607 if (expected.Contains(ToBooleanStub::BOOLEAN)) { | |
1608 // false -> false. | |
1609 __ CompareRoot(reg, Heap::kFalseValueRootIndex); | |
1610 __ b(eq, false_label); | |
1611 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
1612 // We've seen a boolean for the first time -> deopt. | |
1613 __ CompareRoot(reg, Heap::kFalseValueRootIndex); | |
1614 DeoptimizeIf(eq, instr->environment()); | |
1615 } | |
1616 #endif | |
1617 | |
1618 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { | 1587 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { |
1619 // 'null' -> false. | 1588 // 'null' -> false. |
1620 __ CompareRoot(reg, Heap::kNullValueRootIndex); | 1589 __ CompareRoot(reg, Heap::kNullValueRootIndex); |
1621 __ b(eq, false_label); | 1590 __ b(eq, false_label); |
1622 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
1623 // We've seen null for the first time -> deopt. | |
1624 __ CompareRoot(reg, Heap::kNullValueRootIndex); | |
1625 DeoptimizeIf(eq, instr->environment()); | |
1626 } | 1591 } |
1627 | 1592 |
1628 if (expected.Contains(ToBooleanStub::SMI)) { | 1593 if (expected.Contains(ToBooleanStub::SMI)) { |
1629 // Smis: 0 -> false, all other -> true. | 1594 // Smis: 0 -> false, all other -> true. |
1630 __ cmp(reg, Operand(0)); | 1595 __ cmp(reg, Operand(0)); |
1631 __ b(eq, false_label); | 1596 __ b(eq, false_label); |
1632 __ JumpIfSmi(reg, true_label); | 1597 __ JumpIfSmi(reg, true_label); |
1633 } else if (expected.NeedsMap()) { | 1598 } else if (expected.NeedsMap()) { |
1634 // If we need a map later and have a Smi -> deopt. | 1599 // If we need a map later and have a Smi -> deopt. |
1635 __ tst(reg, Operand(kSmiTagMask)); | 1600 __ tst(reg, Operand(kSmiTagMask)); |
1636 DeoptimizeIf(eq, instr->environment()); | 1601 DeoptimizeIf(eq, instr->environment()); |
1637 } | 1602 } |
1638 | 1603 |
1639 const Register map = scratch0(); | 1604 const Register map = scratch0(); |
1640 if (expected.NeedsMap()) { | 1605 if (expected.NeedsMap()) { |
1641 __ ldr(map, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1606 __ ldr(map, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1642 // Everything with a map could be undetectable, so check this now. | 1607 |
1643 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); | 1608 if (expected.CanBeUndetectable()) { |
1644 __ tst(ip, Operand(1 << Map::kIsUndetectable)); | 1609 // Undetectable -> false. |
1645 __ b(ne, false_label); | 1610 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); |
| 1611 __ tst(ip, Operand(1 << Map::kIsUndetectable)); |
| 1612 __ b(ne, false_label); |
| 1613 } |
1646 } | 1614 } |
1647 | 1615 |
1648 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 1616 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { |
1649 // spec object -> true. | 1617 // spec object -> true. |
1650 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE); | 1618 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE); |
1651 __ b(ge, true_label); | 1619 __ b(ge, true_label); |
1652 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
1653 // We've seen a spec object for the first time -> deopt. | |
1654 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE); | |
1655 DeoptimizeIf(ge, instr->environment()); | |
1656 } | 1620 } |
1657 | 1621 |
1658 if (expected.Contains(ToBooleanStub::STRING)) { | 1622 if (expected.Contains(ToBooleanStub::STRING)) { |
1659 // String value -> false iff empty. | 1623 // String value -> false iff empty. |
1660 Label not_string; | 1624 Label not_string; |
1661 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); | 1625 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); |
1662 __ b(ge, ¬_string); | 1626 __ b(ge, ¬_string); |
1663 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); | 1627 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); |
1664 __ cmp(ip, Operand(0)); | 1628 __ cmp(ip, Operand(0)); |
1665 __ b(ne, true_label); | 1629 __ b(ne, true_label); |
1666 __ b(false_label); | 1630 __ b(false_label); |
1667 __ bind(¬_string); | 1631 __ bind(¬_string); |
1668 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
1669 // We've seen a string for the first time -> deopt | |
1670 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); | |
1671 DeoptimizeIf(lt, instr->environment()); | |
1672 } | 1632 } |
1673 | 1633 |
1674 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 1634 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
1675 // heap number -> false iff +0, -0, or NaN. | 1635 // heap number -> false iff +0, -0, or NaN. |
1676 DoubleRegister dbl_scratch = double_scratch0(); | 1636 DoubleRegister dbl_scratch = double_scratch0(); |
1677 Label not_heap_number; | 1637 Label not_heap_number; |
1678 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 1638 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
1679 __ b(ne, ¬_heap_number); | 1639 __ b(ne, ¬_heap_number); |
1680 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 1640 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
1681 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); | 1641 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); |
1682 __ b(vs, false_label); // NaN -> false. | 1642 __ b(vs, false_label); // NaN -> false. |
1683 __ b(eq, false_label); // +0, -0 -> false. | 1643 __ b(eq, false_label); // +0, -0 -> false. |
1684 __ b(true_label); | 1644 __ b(true_label); |
1685 __ bind(¬_heap_number); | 1645 __ bind(¬_heap_number); |
1686 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | |
1687 // We've seen a heap number for the first time -> deopt. | |
1688 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | |
1689 DeoptimizeIf(eq, instr->environment()); | |
1690 } | 1646 } |
1691 | 1647 |
1692 if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { | 1648 // We've seen something for the first time -> deopt. |
1693 // internal objects -> true | 1649 DeoptimizeIf(al, instr->environment()); |
1694 __ b(true_label); | |
1695 } else { | |
1696 // We've seen something for the first time -> deopt. | |
1697 DeoptimizeIf(al, instr->environment()); | |
1698 } | |
1699 } | 1650 } |
1700 } | 1651 } |
1701 } | 1652 } |
1702 | 1653 |
1703 | 1654 |
1704 void LCodeGen::EmitGoto(int block) { | 1655 void LCodeGen::EmitGoto(int block) { |
1705 block = chunk_->LookupDestination(block); | 1656 block = chunk_->LookupDestination(block); |
1706 int next_block = GetNextEmittedBlock(current_block_); | 1657 int next_block = GetNextEmittedBlock(current_block_); |
1707 if (block != next_block) { | 1658 if (block != next_block) { |
1708 __ jmp(chunk_->GetAssemblyLabel(block)); | 1659 __ jmp(chunk_->GetAssemblyLabel(block)); |
(...skipping 1298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3007 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | 2958 __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
3008 DeoptimizeIf(ne, instr->environment()); | 2959 DeoptimizeIf(ne, instr->environment()); |
3009 __ bind(&done); | 2960 __ bind(&done); |
3010 } | 2961 } |
3011 } | 2962 } |
3012 | 2963 |
3013 | 2964 |
3014 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 2965 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
3015 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); | 2966 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); |
3016 Register result = ToRegister(instr->result()); | 2967 Register result = ToRegister(instr->result()); |
3017 Register scratch1 = result; | 2968 Register scratch = scratch0(); |
3018 Register scratch2 = scratch0(); | |
3019 Label done, check_sign_on_zero; | 2969 Label done, check_sign_on_zero; |
3020 | 2970 |
3021 // Extract exponent bits. | 2971 // Extract exponent bits. |
3022 __ vmov(scratch1, input.high()); | 2972 __ vmov(result, input.high()); |
3023 __ ubfx(scratch2, | 2973 __ ubfx(scratch, |
3024 scratch1, | 2974 result, |
3025 HeapNumber::kExponentShift, | 2975 HeapNumber::kExponentShift, |
3026 HeapNumber::kExponentBits); | 2976 HeapNumber::kExponentBits); |
3027 | 2977 |
3028 // If the number is in ]-0.5, +0.5[, the result is +/- 0. | 2978 // If the number is in ]-0.5, +0.5[, the result is +/- 0. |
3029 __ cmp(scratch2, Operand(HeapNumber::kExponentBias - 2)); | 2979 __ cmp(scratch, Operand(HeapNumber::kExponentBias - 2)); |
3030 __ mov(result, Operand(0), LeaveCC, le); | 2980 __ mov(result, Operand(0), LeaveCC, le); |
3031 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 2981 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3032 __ b(le, &check_sign_on_zero); | 2982 __ b(le, &check_sign_on_zero); |
3033 } else { | 2983 } else { |
3034 __ b(le, &done); | 2984 __ b(le, &done); |
3035 } | 2985 } |
3036 | 2986 |
3037 // The following conversion will not work with numbers | 2987 // The following conversion will not work with numbers |
3038 // outside of ]-2^32, 2^32[. | 2988 // outside of ]-2^32, 2^32[. |
3039 __ cmp(scratch2, Operand(HeapNumber::kExponentBias + 32)); | 2989 __ cmp(scratch, Operand(HeapNumber::kExponentBias + 32)); |
3040 DeoptimizeIf(ge, instr->environment()); | 2990 DeoptimizeIf(ge, instr->environment()); |
3041 | 2991 |
3042 // Save the original sign for later comparison. | 2992 // Save the original sign for later comparison. |
3043 __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask)); | 2993 __ and_(scratch, result, Operand(HeapNumber::kSignMask)); |
3044 | 2994 |
3045 __ Vmov(double_scratch0(), 0.5); | 2995 __ Vmov(double_scratch0(), 0.5); |
3046 __ vadd(input, input, double_scratch0()); | 2996 __ vadd(input, input, double_scratch0()); |
3047 | 2997 |
3048 // Check sign of the result: if the sign changed, the input | 2998 // Check sign of the result: if the sign changed, the input |
3049 // value was in ]0.5, 0[ and the result should be -0. | 2999 // value was in ]0.5, 0[ and the result should be -0. |
3050 __ vmov(scratch1, input.high()); | 3000 __ vmov(result, input.high()); |
3051 __ eor(scratch1, scratch1, Operand(scratch2), SetCC); | 3001 __ eor(result, result, Operand(scratch), SetCC); |
3052 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3002 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3053 DeoptimizeIf(mi, instr->environment()); | 3003 DeoptimizeIf(mi, instr->environment()); |
3054 } else { | 3004 } else { |
3055 __ mov(result, Operand(0), LeaveCC, mi); | 3005 __ mov(result, Operand(0), LeaveCC, mi); |
3056 __ b(mi, &done); | 3006 __ b(mi, &done); |
3057 } | 3007 } |
3058 | 3008 |
3059 __ EmitVFPTruncate(kRoundToMinusInf, | 3009 __ EmitVFPTruncate(kRoundToMinusInf, |
3060 double_scratch0().low(), | 3010 double_scratch0().low(), |
3061 input, | 3011 input, |
3062 scratch1, | 3012 result, |
3063 scratch2); | 3013 scratch); |
3064 DeoptimizeIf(ne, instr->environment()); | 3014 DeoptimizeIf(ne, instr->environment()); |
3065 __ vmov(result, double_scratch0().low()); | 3015 __ vmov(result, double_scratch0().low()); |
3066 | 3016 |
3067 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3017 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3068 // Test for -0. | 3018 // Test for -0. |
3069 __ cmp(result, Operand(0)); | 3019 __ cmp(result, Operand(0)); |
3070 __ b(ne, &done); | 3020 __ b(ne, &done); |
3071 __ bind(&check_sign_on_zero); | 3021 __ bind(&check_sign_on_zero); |
3072 __ vmov(scratch1, input.high()); | 3022 __ vmov(scratch, input.high()); |
3073 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | 3023 __ tst(scratch, Operand(HeapNumber::kSignMask)); |
3074 DeoptimizeIf(ne, instr->environment()); | 3024 DeoptimizeIf(ne, instr->environment()); |
3075 } | 3025 } |
3076 __ bind(&done); | 3026 __ bind(&done); |
3077 } | 3027 } |
3078 | 3028 |
3079 | 3029 |
3080 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 3030 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { |
3081 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); | 3031 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); |
3082 DoubleRegister result = ToDoubleRegister(instr->result()); | 3032 DoubleRegister result = ToDoubleRegister(instr->result()); |
3083 __ vsqrt(result, input); | 3033 __ vsqrt(result, input); |
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4388 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); | 4338 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); |
4389 __ tst(ip, Operand(1 << Map::kIsUndetectable)); | 4339 __ tst(ip, Operand(1 << Map::kIsUndetectable)); |
4390 final_branch_condition = eq; | 4340 final_branch_condition = eq; |
4391 | 4341 |
4392 } else if (type_name->Equals(heap()->boolean_symbol())) { | 4342 } else if (type_name->Equals(heap()->boolean_symbol())) { |
4393 __ CompareRoot(input, Heap::kTrueValueRootIndex); | 4343 __ CompareRoot(input, Heap::kTrueValueRootIndex); |
4394 __ b(eq, true_label); | 4344 __ b(eq, true_label); |
4395 __ CompareRoot(input, Heap::kFalseValueRootIndex); | 4345 __ CompareRoot(input, Heap::kFalseValueRootIndex); |
4396 final_branch_condition = eq; | 4346 final_branch_condition = eq; |
4397 | 4347 |
| 4348 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_symbol())) { |
| 4349 __ CompareRoot(input, Heap::kNullValueRootIndex); |
| 4350 final_branch_condition = eq; |
| 4351 |
4398 } else if (type_name->Equals(heap()->undefined_symbol())) { | 4352 } else if (type_name->Equals(heap()->undefined_symbol())) { |
4399 __ CompareRoot(input, Heap::kUndefinedValueRootIndex); | 4353 __ CompareRoot(input, Heap::kUndefinedValueRootIndex); |
4400 __ b(eq, true_label); | 4354 __ b(eq, true_label); |
4401 __ JumpIfSmi(input, false_label); | 4355 __ JumpIfSmi(input, false_label); |
4402 // Check for undetectable objects => true. | 4356 // Check for undetectable objects => true. |
4403 __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset)); | 4357 __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset)); |
4404 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); | 4358 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); |
4405 __ tst(ip, Operand(1 << Map::kIsUndetectable)); | 4359 __ tst(ip, Operand(1 << Map::kIsUndetectable)); |
4406 final_branch_condition = ne; | 4360 final_branch_condition = ne; |
4407 | 4361 |
4408 } else if (type_name->Equals(heap()->function_symbol())) { | 4362 } else if (type_name->Equals(heap()->function_symbol())) { |
4409 __ JumpIfSmi(input, false_label); | 4363 __ JumpIfSmi(input, false_label); |
4410 __ CompareObjectType(input, input, scratch, | 4364 __ CompareObjectType(input, input, scratch, |
4411 FIRST_CALLABLE_SPEC_OBJECT_TYPE); | 4365 FIRST_CALLABLE_SPEC_OBJECT_TYPE); |
4412 final_branch_condition = ge; | 4366 final_branch_condition = ge; |
4413 | 4367 |
4414 } else if (type_name->Equals(heap()->object_symbol())) { | 4368 } else if (type_name->Equals(heap()->object_symbol())) { |
4415 __ JumpIfSmi(input, false_label); | 4369 __ JumpIfSmi(input, false_label); |
4416 __ CompareRoot(input, Heap::kNullValueRootIndex); | 4370 if (!FLAG_harmony_typeof) { |
4417 __ b(eq, true_label); | 4371 __ CompareRoot(input, Heap::kNullValueRootIndex); |
| 4372 __ b(eq, true_label); |
| 4373 } |
4418 __ CompareObjectType(input, input, scratch, | 4374 __ CompareObjectType(input, input, scratch, |
4419 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4375 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); |
4420 __ b(lt, false_label); | 4376 __ b(lt, false_label); |
4421 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4377 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
4422 __ b(gt, false_label); | 4378 __ b(gt, false_label); |
4423 // Check for undetectable objects => false. | 4379 // Check for undetectable objects => false. |
4424 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); | 4380 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); |
4425 __ tst(ip, Operand(1 << Map::kIsUndetectable)); | 4381 __ tst(ip, Operand(1 << Map::kIsUndetectable)); |
4426 final_branch_condition = eq; | 4382 final_branch_condition = eq; |
4427 | 4383 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4571 ASSERT(osr_pc_offset_ == -1); | 4527 ASSERT(osr_pc_offset_ == -1); |
4572 osr_pc_offset_ = masm()->pc_offset(); | 4528 osr_pc_offset_ = masm()->pc_offset(); |
4573 } | 4529 } |
4574 | 4530 |
4575 | 4531 |
4576 | 4532 |
4577 | 4533 |
4578 #undef __ | 4534 #undef __ |
4579 | 4535 |
4580 } } // namespace v8::internal | 4536 } } // namespace v8::internal |
OLD | NEW |