| 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 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 } | 745 } |
| 746 } | 746 } |
| 747 | 747 |
| 748 | 748 |
| 749 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { | 749 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { |
| 750 // Nothing to do. | 750 // Nothing to do. |
| 751 } | 751 } |
| 752 | 752 |
| 753 | 753 |
| 754 void LCodeGen::DoModI(LModI* instr) { | 754 void LCodeGen::DoModI(LModI* instr) { |
| 755 LOperand* right = instr->InputAt(1); | 755 if (instr->hydrogen()->HasPowerOf2Divisor()) { |
| 756 ASSERT(ToRegister(instr->result()).is(rdx)); | 756 Register dividend = ToRegister(instr->InputAt(0)); |
| 757 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); | |
| 758 ASSERT(!ToRegister(instr->InputAt(1)).is(rax)); | |
| 759 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx)); | |
| 760 | 757 |
| 761 Register right_reg = ToRegister(right); | 758 int32_t divisor = |
| 759 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); |
| 762 | 760 |
| 763 // Check for x % 0. | 761 if (divisor < 0) divisor = -divisor; |
| 764 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | |
| 765 __ testl(right_reg, right_reg); | |
| 766 DeoptimizeIf(zero, instr->environment()); | |
| 767 } | |
| 768 | 762 |
| 769 // Sign extend eax to edx. (We are using only the low 32 bits of the values.) | 763 NearLabel positive_dividend, done; |
| 770 __ cdq(); | 764 __ testl(dividend, dividend); |
| 771 | 765 __ j(not_sign, &positive_dividend); |
| 772 // Check for (0 % -x) that will produce negative zero. | 766 __ negl(dividend); |
| 773 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 767 __ andl(dividend, Immediate(divisor - 1)); |
| 774 NearLabel positive_left; | 768 __ negl(dividend); |
| 775 NearLabel done; | 769 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 776 __ testl(rax, rax); | 770 __ j(not_zero, &done); |
| 777 __ j(not_sign, &positive_left); | 771 DeoptimizeIf(no_condition, instr->environment()); |
| 778 __ idivl(right_reg); | 772 } |
| 779 | 773 __ bind(&positive_dividend); |
| 780 // Test the remainder for 0, because then the result would be -0. | 774 __ andl(dividend, Immediate(divisor - 1)); |
| 781 __ testl(rdx, rdx); | |
| 782 __ j(not_zero, &done); | |
| 783 | |
| 784 DeoptimizeIf(no_condition, instr->environment()); | |
| 785 __ bind(&positive_left); | |
| 786 __ idivl(right_reg); | |
| 787 __ bind(&done); | 775 __ bind(&done); |
| 788 } else { | 776 } else { |
| 789 __ idivl(right_reg); | 777 LOperand* right = instr->InputAt(1); |
| 778 Register right_reg = ToRegister(right); |
| 779 |
| 780 ASSERT(ToRegister(instr->result()).is(rdx)); |
| 781 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); |
| 782 ASSERT(!right_reg.is(rax)); |
| 783 ASSERT(!right_reg.is(rdx)); |
| 784 |
| 785 // Check for x % 0. |
| 786 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { |
| 787 __ testl(right_reg, right_reg); |
| 788 DeoptimizeIf(zero, instr->environment()); |
| 789 } |
| 790 |
| 791 // Sign extend eax to edx. |
| 792 // (We are using only the low 32 bits of the values.) |
| 793 __ cdq(); |
| 794 |
| 795 // Check for (0 % -x) that will produce negative zero. |
| 796 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 797 NearLabel positive_left; |
| 798 NearLabel done; |
| 799 __ testl(rax, rax); |
| 800 __ j(not_sign, &positive_left); |
| 801 __ idivl(right_reg); |
| 802 |
| 803 // Test the remainder for 0, because then the result would be -0. |
| 804 __ testl(rdx, rdx); |
| 805 __ j(not_zero, &done); |
| 806 |
| 807 DeoptimizeIf(no_condition, instr->environment()); |
| 808 __ bind(&positive_left); |
| 809 __ idivl(right_reg); |
| 810 __ bind(&done); |
| 811 } else { |
| 812 __ idivl(right_reg); |
| 813 } |
| 790 } | 814 } |
| 791 } | 815 } |
| 792 | 816 |
| 793 | 817 |
| 794 void LCodeGen::DoDivI(LDivI* instr) { | 818 void LCodeGen::DoDivI(LDivI* instr) { |
| 795 LOperand* right = instr->InputAt(1); | 819 LOperand* right = instr->InputAt(1); |
| 796 ASSERT(ToRegister(instr->result()).is(rax)); | 820 ASSERT(ToRegister(instr->result()).is(rax)); |
| 797 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); | 821 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); |
| 798 ASSERT(!ToRegister(instr->InputAt(1)).is(rax)); | 822 ASSERT(!ToRegister(instr->InputAt(1)).is(rax)); |
| 799 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx)); | 823 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx)); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { | 1076 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { |
| 1053 Register result = ToRegister(instr->result()); | 1077 Register result = ToRegister(instr->result()); |
| 1054 Register array = ToRegister(instr->InputAt(0)); | 1078 Register array = ToRegister(instr->InputAt(0)); |
| 1055 __ movq(result, FieldOperand(array, FixedArray::kLengthOffset)); | 1079 __ movq(result, FieldOperand(array, FixedArray::kLengthOffset)); |
| 1056 } | 1080 } |
| 1057 | 1081 |
| 1058 | 1082 |
| 1059 void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) { | 1083 void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) { |
| 1060 Register result = ToRegister(instr->result()); | 1084 Register result = ToRegister(instr->result()); |
| 1061 Register array = ToRegister(instr->InputAt(0)); | 1085 Register array = ToRegister(instr->InputAt(0)); |
| 1062 __ movq(result, FieldOperand(array, ExternalPixelArray::kLengthOffset)); | 1086 __ movl(result, FieldOperand(array, ExternalPixelArray::kLengthOffset)); |
| 1063 } | 1087 } |
| 1064 | 1088 |
| 1065 | 1089 |
| 1066 void LCodeGen::DoValueOf(LValueOf* instr) { | 1090 void LCodeGen::DoValueOf(LValueOf* instr) { |
| 1067 Register input = ToRegister(instr->InputAt(0)); | 1091 Register input = ToRegister(instr->InputAt(0)); |
| 1068 Register result = ToRegister(instr->result()); | 1092 Register result = ToRegister(instr->result()); |
| 1069 ASSERT(input.is(result)); | 1093 ASSERT(input.is(result)); |
| 1070 NearLabel done; | 1094 NearLabel done; |
| 1071 // If the object is a smi return the object. | 1095 // If the object is a smi return the object. |
| 1072 __ JumpIfSmi(input, &done); | 1096 __ JumpIfSmi(input, &done); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 } else if (r.IsDouble()) { | 1227 } else if (r.IsDouble()) { |
| 1204 XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); | 1228 XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); |
| 1205 __ xorpd(xmm0, xmm0); | 1229 __ xorpd(xmm0, xmm0); |
| 1206 __ ucomisd(reg, xmm0); | 1230 __ ucomisd(reg, xmm0); |
| 1207 EmitBranch(true_block, false_block, not_equal); | 1231 EmitBranch(true_block, false_block, not_equal); |
| 1208 } else { | 1232 } else { |
| 1209 ASSERT(r.IsTagged()); | 1233 ASSERT(r.IsTagged()); |
| 1210 Register reg = ToRegister(instr->InputAt(0)); | 1234 Register reg = ToRegister(instr->InputAt(0)); |
| 1211 HType type = instr->hydrogen()->type(); | 1235 HType type = instr->hydrogen()->type(); |
| 1212 if (type.IsBoolean()) { | 1236 if (type.IsBoolean()) { |
| 1213 __ Cmp(reg, Factory::true_value()); | 1237 __ CompareRoot(reg, Heap::kTrueValueRootIndex); |
| 1214 EmitBranch(true_block, false_block, equal); | 1238 EmitBranch(true_block, false_block, equal); |
| 1215 } else if (type.IsSmi()) { | 1239 } else if (type.IsSmi()) { |
| 1216 __ SmiCompare(reg, Smi::FromInt(0)); | 1240 __ SmiCompare(reg, Smi::FromInt(0)); |
| 1217 EmitBranch(true_block, false_block, not_equal); | 1241 EmitBranch(true_block, false_block, not_equal); |
| 1218 } else { | 1242 } else { |
| 1219 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 1243 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 1220 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1244 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1221 | 1245 |
| 1222 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); | 1246 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); |
| 1223 __ j(equal, false_label); | 1247 __ j(equal, false_label); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1470 instr->hydrogen()->type().IsSmi()) { | 1494 instr->hydrogen()->type().IsSmi()) { |
| 1471 // If the expression is known to untagged or smi, then it's definitely | 1495 // If the expression is known to untagged or smi, then it's definitely |
| 1472 // not null, and it can't be a an undetectable object. | 1496 // not null, and it can't be a an undetectable object. |
| 1473 // Jump directly to the false block. | 1497 // Jump directly to the false block. |
| 1474 EmitGoto(false_block); | 1498 EmitGoto(false_block); |
| 1475 return; | 1499 return; |
| 1476 } | 1500 } |
| 1477 | 1501 |
| 1478 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1502 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1479 | 1503 |
| 1480 __ Cmp(reg, Factory::null_value()); | 1504 __ CompareRoot(reg, Heap::kNullValueRootIndex); |
| 1481 if (instr->is_strict()) { | 1505 if (instr->is_strict()) { |
| 1482 EmitBranch(true_block, false_block, equal); | 1506 EmitBranch(true_block, false_block, equal); |
| 1483 } else { | 1507 } else { |
| 1484 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 1508 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 1485 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1509 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1486 __ j(equal, true_label); | 1510 __ j(equal, true_label); |
| 1487 __ Cmp(reg, Factory::undefined_value()); | 1511 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); |
| 1488 __ j(equal, true_label); | 1512 __ j(equal, true_label); |
| 1489 __ JumpIfSmi(reg, false_label); | 1513 __ JumpIfSmi(reg, false_label); |
| 1490 // Check for undetectable objects by looking in the bit field in | 1514 // Check for undetectable objects by looking in the bit field in |
| 1491 // the map. The object has already been smi checked. | 1515 // the map. The object has already been smi checked. |
| 1492 Register scratch = ToRegister(instr->TempAt(0)); | 1516 Register scratch = ToRegister(instr->TempAt(0)); |
| 1493 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset)); | 1517 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset)); |
| 1494 __ testb(FieldOperand(scratch, Map::kBitFieldOffset), | 1518 __ testb(FieldOperand(scratch, Map::kBitFieldOffset), |
| 1495 Immediate(1 << Map::kIsUndetectable)); | 1519 Immediate(1 << Map::kIsUndetectable)); |
| 1496 EmitBranch(true_block, false_block, not_zero); | 1520 EmitBranch(true_block, false_block, not_zero); |
| 1497 } | 1521 } |
| (...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2085 __ bind(&done); | 2109 __ bind(&done); |
| 2086 } | 2110 } |
| 2087 | 2111 |
| 2088 | 2112 |
| 2089 void LCodeGen::DoLoadElements(LLoadElements* instr) { | 2113 void LCodeGen::DoLoadElements(LLoadElements* instr) { |
| 2090 Register result = ToRegister(instr->result()); | 2114 Register result = ToRegister(instr->result()); |
| 2091 Register input = ToRegister(instr->InputAt(0)); | 2115 Register input = ToRegister(instr->InputAt(0)); |
| 2092 __ movq(result, FieldOperand(input, JSObject::kElementsOffset)); | 2116 __ movq(result, FieldOperand(input, JSObject::kElementsOffset)); |
| 2093 if (FLAG_debug_code) { | 2117 if (FLAG_debug_code) { |
| 2094 NearLabel done; | 2118 NearLabel done; |
| 2095 __ Cmp(FieldOperand(result, HeapObject::kMapOffset), | 2119 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), |
| 2096 Factory::fixed_array_map()); | 2120 Heap::kFixedArrayMapRootIndex); |
| 2097 __ j(equal, &done); | 2121 __ j(equal, &done); |
| 2098 __ Cmp(FieldOperand(result, HeapObject::kMapOffset), | 2122 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), |
| 2099 Factory::external_pixel_array_map()); | 2123 Heap::kExternalPixelArrayMapRootIndex); |
| 2100 __ j(equal, &done); | 2124 __ j(equal, &done); |
| 2101 __ Cmp(FieldOperand(result, HeapObject::kMapOffset), | 2125 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), |
| 2102 Factory::fixed_cow_array_map()); | 2126 Heap::kFixedCOWArrayMapRootIndex); |
| 2103 __ Check(equal, "Check for fast elements failed."); | 2127 __ Check(equal, "Check for fast elements failed."); |
| 2104 __ bind(&done); | 2128 __ bind(&done); |
| 2105 } | 2129 } |
| 2106 } | 2130 } |
| 2107 | 2131 |
| 2108 | 2132 |
| 2109 void LCodeGen::DoLoadExternalArrayPointer( | 2133 void LCodeGen::DoLoadExternalArrayPointer( |
| 2110 LLoadExternalArrayPointer* instr) { | 2134 LLoadExternalArrayPointer* instr) { |
| 2111 Register result = ToRegister(instr->result()); | 2135 Register result = ToRegister(instr->result()); |
| 2112 Register input = ToRegister(instr->InputAt(0)); | 2136 Register input = ToRegister(instr->InputAt(0)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2139 Register result = ToRegister(instr->result()); | 2163 Register result = ToRegister(instr->result()); |
| 2140 ASSERT(result.is(elements)); | 2164 ASSERT(result.is(elements)); |
| 2141 | 2165 |
| 2142 // Load the result. | 2166 // Load the result. |
| 2143 __ movq(result, FieldOperand(elements, | 2167 __ movq(result, FieldOperand(elements, |
| 2144 key, | 2168 key, |
| 2145 times_pointer_size, | 2169 times_pointer_size, |
| 2146 FixedArray::kHeaderSize)); | 2170 FixedArray::kHeaderSize)); |
| 2147 | 2171 |
| 2148 // Check for the hole value. | 2172 // Check for the hole value. |
| 2149 __ Cmp(result, Factory::the_hole_value()); | 2173 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
| 2150 DeoptimizeIf(equal, instr->environment()); | 2174 DeoptimizeIf(equal, instr->environment()); |
| 2151 } | 2175 } |
| 2152 | 2176 |
| 2153 | 2177 |
| 2154 void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) { | 2178 void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) { |
| 2155 Register external_elements = ToRegister(instr->external_pointer()); | 2179 Register external_elements = ToRegister(instr->external_pointer()); |
| 2156 Register key = ToRegister(instr->key()); | 2180 Register key = ToRegister(instr->key()); |
| 2157 Register result = ToRegister(instr->result()); | 2181 Register result = ToRegister(instr->result()); |
| 2158 ASSERT(result.is(external_elements)); | 2182 ASSERT(result.is(external_elements)); |
| 2159 | 2183 |
| (...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2971 instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex); | 2995 instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex); |
| 2972 if (FLAG_debug_code) { | 2996 if (FLAG_debug_code) { |
| 2973 __ AbortIfNotSmi(rax); | 2997 __ AbortIfNotSmi(rax); |
| 2974 } | 2998 } |
| 2975 __ SmiToInteger32(rax, rax); | 2999 __ SmiToInteger32(rax, rax); |
| 2976 __ StoreToSafepointRegisterSlot(result, rax); | 3000 __ StoreToSafepointRegisterSlot(result, rax); |
| 2977 __ PopSafepointRegisters(); | 3001 __ PopSafepointRegisters(); |
| 2978 } | 3002 } |
| 2979 | 3003 |
| 2980 | 3004 |
| 3005 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { |
| 3006 class DeferredStringCharFromCode: public LDeferredCode { |
| 3007 public: |
| 3008 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) |
| 3009 : LDeferredCode(codegen), instr_(instr) { } |
| 3010 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } |
| 3011 private: |
| 3012 LStringCharFromCode* instr_; |
| 3013 }; |
| 3014 |
| 3015 DeferredStringCharFromCode* deferred = |
| 3016 new DeferredStringCharFromCode(this, instr); |
| 3017 |
| 3018 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); |
| 3019 Register char_code = ToRegister(instr->char_code()); |
| 3020 Register result = ToRegister(instr->result()); |
| 3021 ASSERT(!char_code.is(result)); |
| 3022 |
| 3023 __ cmpl(char_code, Immediate(String::kMaxAsciiCharCode)); |
| 3024 __ j(above, deferred->entry()); |
| 3025 __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); |
| 3026 __ movq(result, FieldOperand(result, |
| 3027 char_code, times_pointer_size, |
| 3028 FixedArray::kHeaderSize)); |
| 3029 __ CompareRoot(result, Heap::kUndefinedValueRootIndex); |
| 3030 __ j(equal, deferred->entry()); |
| 3031 __ bind(deferred->exit()); |
| 3032 } |
| 3033 |
| 3034 |
| 3035 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { |
| 3036 Register char_code = ToRegister(instr->char_code()); |
| 3037 Register result = ToRegister(instr->result()); |
| 3038 |
| 3039 // TODO(3095996): Get rid of this. For now, we need to make the |
| 3040 // result register contain a valid pointer because it is already |
| 3041 // contained in the register pointer map. |
| 3042 __ Set(result, 0); |
| 3043 |
| 3044 __ PushSafepointRegisters(); |
| 3045 __ Integer32ToSmi(char_code, char_code); |
| 3046 __ push(char_code); |
| 3047 __ CallRuntimeSaveDoubles(Runtime::kCharFromCode); |
| 3048 RecordSafepointWithRegisters( |
| 3049 instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex); |
| 3050 __ StoreToSafepointRegisterSlot(result, rax); |
| 3051 __ PopSafepointRegisters(); |
| 3052 } |
| 3053 |
| 3054 |
| 2981 void LCodeGen::DoStringLength(LStringLength* instr) { | 3055 void LCodeGen::DoStringLength(LStringLength* instr) { |
| 2982 Register string = ToRegister(instr->string()); | 3056 Register string = ToRegister(instr->string()); |
| 2983 Register result = ToRegister(instr->result()); | 3057 Register result = ToRegister(instr->result()); |
| 2984 __ movq(result, FieldOperand(string, String::kLengthOffset)); | 3058 __ movq(result, FieldOperand(string, String::kLengthOffset)); |
| 2985 } | 3059 } |
| 2986 | 3060 |
| 2987 | 3061 |
| 2988 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 3062 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
| 2989 LOperand* input = instr->InputAt(0); | 3063 LOperand* input = instr->InputAt(0); |
| 2990 ASSERT(input->IsRegister() || input->IsStackSlot()); | 3064 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3427 // space for nested functions that don't need literals cloning. | 3501 // space for nested functions that don't need literals cloning. |
| 3428 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); | 3502 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); |
| 3429 bool pretenure = instr->hydrogen()->pretenure(); | 3503 bool pretenure = instr->hydrogen()->pretenure(); |
| 3430 if (shared_info->num_literals() == 0 && !pretenure) { | 3504 if (shared_info->num_literals() == 0 && !pretenure) { |
| 3431 FastNewClosureStub stub; | 3505 FastNewClosureStub stub; |
| 3432 __ Push(shared_info); | 3506 __ Push(shared_info); |
| 3433 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 3507 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 3434 } else { | 3508 } else { |
| 3435 __ push(rsi); | 3509 __ push(rsi); |
| 3436 __ Push(shared_info); | 3510 __ Push(shared_info); |
| 3437 __ Push(pretenure ? Factory::true_value() : Factory::false_value()); | 3511 __ PushRoot(pretenure ? |
| 3512 Heap::kTrueValueRootIndex : |
| 3513 Heap::kFalseValueRootIndex); |
| 3438 CallRuntime(Runtime::kNewClosure, 3, instr); | 3514 CallRuntime(Runtime::kNewClosure, 3, instr); |
| 3439 } | 3515 } |
| 3440 } | 3516 } |
| 3441 | 3517 |
| 3442 | 3518 |
| 3443 void LCodeGen::DoTypeof(LTypeof* instr) { | 3519 void LCodeGen::DoTypeof(LTypeof* instr) { |
| 3444 LOperand* input = instr->InputAt(0); | 3520 LOperand* input = instr->InputAt(0); |
| 3445 if (input->IsConstantOperand()) { | 3521 if (input->IsConstantOperand()) { |
| 3446 __ Push(ToHandle(LConstantOperand::cast(input))); | 3522 __ Push(ToHandle(LConstantOperand::cast(input))); |
| 3447 } else if (input->IsRegister()) { | 3523 } else if (input->IsRegister()) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3510 } | 3586 } |
| 3511 | 3587 |
| 3512 | 3588 |
| 3513 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 3589 Condition LCodeGen::EmitTypeofIs(Label* true_label, |
| 3514 Label* false_label, | 3590 Label* false_label, |
| 3515 Register input, | 3591 Register input, |
| 3516 Handle<String> type_name) { | 3592 Handle<String> type_name) { |
| 3517 Condition final_branch_condition = no_condition; | 3593 Condition final_branch_condition = no_condition; |
| 3518 if (type_name->Equals(Heap::number_symbol())) { | 3594 if (type_name->Equals(Heap::number_symbol())) { |
| 3519 __ JumpIfSmi(input, true_label); | 3595 __ JumpIfSmi(input, true_label); |
| 3520 __ Cmp(FieldOperand(input, HeapObject::kMapOffset), | 3596 __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset), |
| 3521 Factory::heap_number_map()); | 3597 Heap::kHeapNumberMapRootIndex); |
| 3598 |
| 3522 final_branch_condition = equal; | 3599 final_branch_condition = equal; |
| 3523 | 3600 |
| 3524 } else if (type_name->Equals(Heap::string_symbol())) { | 3601 } else if (type_name->Equals(Heap::string_symbol())) { |
| 3525 __ JumpIfSmi(input, false_label); | 3602 __ JumpIfSmi(input, false_label); |
| 3526 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); | 3603 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); |
| 3527 __ j(above_equal, false_label); | 3604 __ j(above_equal, false_label); |
| 3528 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 3605 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
| 3529 Immediate(1 << Map::kIsUndetectable)); | 3606 Immediate(1 << Map::kIsUndetectable)); |
| 3530 final_branch_condition = zero; | 3607 final_branch_condition = zero; |
| 3531 | 3608 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3691 RegisterEnvironmentForDeoptimization(environment); | 3768 RegisterEnvironmentForDeoptimization(environment); |
| 3692 ASSERT(osr_pc_offset_ == -1); | 3769 ASSERT(osr_pc_offset_ == -1); |
| 3693 osr_pc_offset_ = masm()->pc_offset(); | 3770 osr_pc_offset_ = masm()->pc_offset(); |
| 3694 } | 3771 } |
| 3695 | 3772 |
| 3696 #undef __ | 3773 #undef __ |
| 3697 | 3774 |
| 3698 } } // namespace v8::internal | 3775 } } // namespace v8::internal |
| 3699 | 3776 |
| 3700 #endif // V8_TARGET_ARCH_X64 | 3777 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |