| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/arm64/lithium-codegen-arm64.h" | 7 #include "src/arm64/lithium-codegen-arm64.h" |
| 8 #include "src/arm64/lithium-gap-resolver-arm64.h" | 8 #include "src/arm64/lithium-gap-resolver-arm64.h" |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 } | 1116 } |
| 1117 | 1117 |
| 1118 | 1118 |
| 1119 void LCodeGen::DeoptimizeIfNotRoot(Register rt, Heap::RootListIndex index, | 1119 void LCodeGen::DeoptimizeIfNotRoot(Register rt, Heap::RootListIndex index, |
| 1120 LInstruction* instr) { | 1120 LInstruction* instr) { |
| 1121 __ CompareRoot(rt, index); | 1121 __ CompareRoot(rt, index); |
| 1122 DeoptimizeIf(ne, instr); | 1122 DeoptimizeIf(ne, instr); |
| 1123 } | 1123 } |
| 1124 | 1124 |
| 1125 | 1125 |
| 1126 void LCodeGen::DeoptimizeIfNotHeapNumber(Register object, LInstruction* instr) { |
| 1127 __ CompareObjectMap(object, Heap::kHeapNumberMapRootIndex); |
| 1128 DeoptimizeIf(ne, instr); |
| 1129 } |
| 1130 |
| 1131 |
| 1126 void LCodeGen::DeoptimizeIfMinusZero(DoubleRegister input, | 1132 void LCodeGen::DeoptimizeIfMinusZero(DoubleRegister input, |
| 1127 LInstruction* instr) { | 1133 LInstruction* instr) { |
| 1128 __ TestForMinusZero(input); | 1134 __ TestForMinusZero(input); |
| 1129 DeoptimizeIf(vs, instr); | 1135 DeoptimizeIf(vs, instr); |
| 1130 } | 1136 } |
| 1131 | 1137 |
| 1132 | 1138 |
| 1133 void LCodeGen::DeoptimizeIfBitSet(Register rt, int bit, LInstruction* instr) { | 1139 void LCodeGen::DeoptimizeIfBitSet(Register rt, int bit, LInstruction* instr) { |
| 1134 DeoptimizeBranch(instr, reg_bit_set, rt, bit); | 1140 DeoptimizeBranch(instr, reg_bit_set, rt, bit); |
| 1135 } | 1141 } |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1370 const BranchGenerator& branch) { | 1376 const BranchGenerator& branch) { |
| 1371 int left_block = instr->TrueDestination(chunk_); | 1377 int left_block = instr->TrueDestination(chunk_); |
| 1372 int right_block = instr->FalseDestination(chunk_); | 1378 int right_block = instr->FalseDestination(chunk_); |
| 1373 | 1379 |
| 1374 int next_block = GetNextEmittedBlock(); | 1380 int next_block = GetNextEmittedBlock(); |
| 1375 | 1381 |
| 1376 if (right_block == left_block) { | 1382 if (right_block == left_block) { |
| 1377 EmitGoto(left_block); | 1383 EmitGoto(left_block); |
| 1378 } else if (left_block == next_block) { | 1384 } else if (left_block == next_block) { |
| 1379 branch.EmitInverted(chunk_->GetAssemblyLabel(right_block)); | 1385 branch.EmitInverted(chunk_->GetAssemblyLabel(right_block)); |
| 1380 } else if (right_block == next_block) { | |
| 1381 branch.Emit(chunk_->GetAssemblyLabel(left_block)); | |
| 1382 } else { | 1386 } else { |
| 1383 branch.Emit(chunk_->GetAssemblyLabel(left_block)); | 1387 branch.Emit(chunk_->GetAssemblyLabel(left_block)); |
| 1384 __ B(chunk_->GetAssemblyLabel(right_block)); | 1388 if (right_block != next_block) { |
| 1389 __ B(chunk_->GetAssemblyLabel(right_block)); |
| 1390 } |
| 1385 } | 1391 } |
| 1386 } | 1392 } |
| 1387 | 1393 |
| 1388 | 1394 |
| 1389 template<class InstrType> | 1395 template<class InstrType> |
| 1390 void LCodeGen::EmitBranch(InstrType instr, Condition condition) { | 1396 void LCodeGen::EmitBranch(InstrType instr, Condition condition) { |
| 1391 DCHECK((condition != al) && (condition != nv)); | 1397 DCHECK((condition != al) && (condition != nv)); |
| 1392 BranchOnCondition branch(this, condition); | 1398 BranchOnCondition branch(this, condition); |
| 1393 EmitBranchGeneric(instr, branch); | 1399 EmitBranchGeneric(instr, branch); |
| 1394 } | 1400 } |
| (...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2292 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { | 2298 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { |
| 2293 Register input = ToRegister32(instr->unclamped()); | 2299 Register input = ToRegister32(instr->unclamped()); |
| 2294 Register result = ToRegister32(instr->result()); | 2300 Register result = ToRegister32(instr->result()); |
| 2295 __ ClampInt32ToUint8(result, input); | 2301 __ ClampInt32ToUint8(result, input); |
| 2296 } | 2302 } |
| 2297 | 2303 |
| 2298 | 2304 |
| 2299 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { | 2305 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { |
| 2300 Register input = ToRegister(instr->unclamped()); | 2306 Register input = ToRegister(instr->unclamped()); |
| 2301 Register result = ToRegister32(instr->result()); | 2307 Register result = ToRegister32(instr->result()); |
| 2302 Register scratch = ToRegister(instr->temp1()); | |
| 2303 Label done; | 2308 Label done; |
| 2304 | 2309 |
| 2305 // Both smi and heap number cases are handled. | 2310 // Both smi and heap number cases are handled. |
| 2306 Label is_not_smi; | 2311 Label is_not_smi; |
| 2307 __ JumpIfNotSmi(input, &is_not_smi); | 2312 __ JumpIfNotSmi(input, &is_not_smi); |
| 2308 __ SmiUntag(result.X(), input); | 2313 __ SmiUntag(result.X(), input); |
| 2309 __ ClampInt32ToUint8(result); | 2314 __ ClampInt32ToUint8(result); |
| 2310 __ B(&done); | 2315 __ B(&done); |
| 2311 | 2316 |
| 2312 __ Bind(&is_not_smi); | 2317 __ Bind(&is_not_smi); |
| 2313 | 2318 |
| 2314 // Check for heap number. | 2319 // Check for heap number. |
| 2315 Label is_heap_number; | 2320 Label is_heap_number; |
| 2316 __ Ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 2321 __ JumpIfHeapNumber(input, &is_heap_number); |
| 2317 __ JumpIfRoot(scratch, Heap::kHeapNumberMapRootIndex, &is_heap_number); | |
| 2318 | 2322 |
| 2319 // Check for undefined. Undefined is coverted to zero for clamping conversion. | 2323 // Check for undefined. Undefined is coverted to zero for clamping conversion. |
| 2320 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr); | 2324 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr); |
| 2321 __ Mov(result, 0); | 2325 __ Mov(result, 0); |
| 2322 __ B(&done); | 2326 __ B(&done); |
| 2323 | 2327 |
| 2324 // Heap number case. | 2328 // Heap number case. |
| 2325 __ Bind(&is_heap_number); | 2329 __ Bind(&is_heap_number); |
| 2326 DoubleRegister dbl_scratch = double_scratch(); | 2330 DoubleRegister dbl_scratch = double_scratch(); |
| 2327 DoubleRegister dbl_scratch2 = ToDoubleRegister(instr->temp2()); | 2331 DoubleRegister dbl_scratch2 = ToDoubleRegister(instr->temp1()); |
| 2328 __ Ldr(dbl_scratch, FieldMemOperand(input, HeapNumber::kValueOffset)); | 2332 __ Ldr(dbl_scratch, FieldMemOperand(input, HeapNumber::kValueOffset)); |
| 2329 __ ClampDoubleToUint8(result, dbl_scratch, dbl_scratch2); | 2333 __ ClampDoubleToUint8(result, dbl_scratch, dbl_scratch2); |
| 2330 | 2334 |
| 2331 __ Bind(&done); | 2335 __ Bind(&done); |
| 2332 } | 2336 } |
| 2333 | 2337 |
| 2334 | 2338 |
| 2335 void LCodeGen::DoDoubleBits(LDoubleBits* instr) { | 2339 void LCodeGen::DoDoubleBits(LDoubleBits* instr) { |
| 2336 DoubleRegister value_reg = ToDoubleRegister(instr->value()); | 2340 DoubleRegister value_reg = ToDoubleRegister(instr->value()); |
| 2337 Register result_reg = ToRegister(instr->result()); | 2341 Register result_reg = ToRegister(instr->result()); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2453 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) { | 2457 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) { |
| 2454 Representation rep = instr->hydrogen()->value()->representation(); | 2458 Representation rep = instr->hydrogen()->value()->representation(); |
| 2455 DCHECK(!rep.IsInteger32()); | 2459 DCHECK(!rep.IsInteger32()); |
| 2456 Register scratch = ToRegister(instr->temp()); | 2460 Register scratch = ToRegister(instr->temp()); |
| 2457 | 2461 |
| 2458 if (rep.IsDouble()) { | 2462 if (rep.IsDouble()) { |
| 2459 __ JumpIfMinusZero(ToDoubleRegister(instr->value()), | 2463 __ JumpIfMinusZero(ToDoubleRegister(instr->value()), |
| 2460 instr->TrueLabel(chunk())); | 2464 instr->TrueLabel(chunk())); |
| 2461 } else { | 2465 } else { |
| 2462 Register value = ToRegister(instr->value()); | 2466 Register value = ToRegister(instr->value()); |
| 2463 __ CheckMap(value, scratch, Heap::kHeapNumberMapRootIndex, | 2467 __ JumpIfNotHeapNumber(value, instr->FalseLabel(chunk()), DO_SMI_CHECK); |
| 2464 instr->FalseLabel(chunk()), DO_SMI_CHECK); | |
| 2465 __ Ldr(scratch, FieldMemOperand(value, HeapNumber::kValueOffset)); | 2468 __ Ldr(scratch, FieldMemOperand(value, HeapNumber::kValueOffset)); |
| 2466 __ JumpIfMinusZero(scratch, instr->TrueLabel(chunk())); | 2469 __ JumpIfMinusZero(scratch, instr->TrueLabel(chunk())); |
| 2467 } | 2470 } |
| 2468 EmitGoto(instr->FalseDestination(chunk())); | 2471 EmitGoto(instr->FalseDestination(chunk())); |
| 2469 } | 2472 } |
| 2470 | 2473 |
| 2471 | 2474 |
| 2472 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { | 2475 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { |
| 2473 LOperand* left = instr->left(); | 2476 LOperand* left = instr->left(); |
| 2474 LOperand* right = instr->right(); | 2477 LOperand* right = instr->right(); |
| (...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3750 DCHECK(ToRegister(instr->context()).is(cp)); | 3753 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3751 Register input = ToRegister(instr->value()); | 3754 Register input = ToRegister(instr->value()); |
| 3752 Register temp1 = ToRegister(instr->temp1()); | 3755 Register temp1 = ToRegister(instr->temp1()); |
| 3753 Register temp2 = ToRegister(instr->temp2()); | 3756 Register temp2 = ToRegister(instr->temp2()); |
| 3754 Register result_bits = ToRegister(instr->temp3()); | 3757 Register result_bits = ToRegister(instr->temp3()); |
| 3755 Register result = ToRegister(instr->result()); | 3758 Register result = ToRegister(instr->result()); |
| 3756 | 3759 |
| 3757 Label runtime_allocation; | 3760 Label runtime_allocation; |
| 3758 | 3761 |
| 3759 // Deoptimize if the input is not a HeapNumber. | 3762 // Deoptimize if the input is not a HeapNumber. |
| 3760 __ Ldr(temp1, FieldMemOperand(input, HeapObject::kMapOffset)); | 3763 DeoptimizeIfNotHeapNumber(input, instr); |
| 3761 DeoptimizeIfNotRoot(temp1, Heap::kHeapNumberMapRootIndex, instr); | |
| 3762 | 3764 |
| 3763 // If the argument is positive, we can return it as-is, without any need to | 3765 // If the argument is positive, we can return it as-is, without any need to |
| 3764 // allocate a new HeapNumber for the result. We have to do this in integer | 3766 // allocate a new HeapNumber for the result. We have to do this in integer |
| 3765 // registers (rather than with fabs) because we need to be able to distinguish | 3767 // registers (rather than with fabs) because we need to be able to distinguish |
| 3766 // the two zeroes. | 3768 // the two zeroes. |
| 3767 __ Ldr(result_bits, FieldMemOperand(input, HeapNumber::kValueOffset)); | 3769 __ Ldr(result_bits, FieldMemOperand(input, HeapNumber::kValueOffset)); |
| 3768 __ Mov(result, input); | 3770 __ Mov(result, input); |
| 3769 __ Tbz(result_bits, kXSignBit, exit); | 3771 __ Tbz(result_bits, kXSignBit, exit); |
| 3770 | 3772 |
| 3771 // Calculate abs(input) by clearing the sign bit. | 3773 // Calculate abs(input) by clearing the sign bit. |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4085 ToRegister(instr->right()).is(integer_exponent)); | 4087 ToRegister(instr->right()).is(integer_exponent)); |
| 4086 DCHECK(ToDoubleRegister(instr->left()).is(d0)); | 4088 DCHECK(ToDoubleRegister(instr->left()).is(d0)); |
| 4087 DCHECK(ToDoubleRegister(instr->result()).is(d0)); | 4089 DCHECK(ToDoubleRegister(instr->result()).is(d0)); |
| 4088 | 4090 |
| 4089 if (exponent_type.IsSmi()) { | 4091 if (exponent_type.IsSmi()) { |
| 4090 MathPowStub stub(isolate(), MathPowStub::TAGGED); | 4092 MathPowStub stub(isolate(), MathPowStub::TAGGED); |
| 4091 __ CallStub(&stub); | 4093 __ CallStub(&stub); |
| 4092 } else if (exponent_type.IsTagged()) { | 4094 } else if (exponent_type.IsTagged()) { |
| 4093 Label no_deopt; | 4095 Label no_deopt; |
| 4094 __ JumpIfSmi(tagged_exponent, &no_deopt); | 4096 __ JumpIfSmi(tagged_exponent, &no_deopt); |
| 4095 DCHECK(!x0.is(tagged_exponent)); | 4097 DeoptimizeIfNotHeapNumber(tagged_exponent, instr); |
| 4096 __ Ldr(x0, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); | |
| 4097 DeoptimizeIfNotRoot(x0, Heap::kHeapNumberMapRootIndex, instr); | |
| 4098 __ Bind(&no_deopt); | 4098 __ Bind(&no_deopt); |
| 4099 MathPowStub stub(isolate(), MathPowStub::TAGGED); | 4099 MathPowStub stub(isolate(), MathPowStub::TAGGED); |
| 4100 __ CallStub(&stub); | 4100 __ CallStub(&stub); |
| 4101 } else if (exponent_type.IsInteger32()) { | 4101 } else if (exponent_type.IsInteger32()) { |
| 4102 // Ensure integer exponent has no garbage in top 32-bits, as MathPowStub | 4102 // Ensure integer exponent has no garbage in top 32-bits, as MathPowStub |
| 4103 // supports large integer exponents. | 4103 // supports large integer exponents. |
| 4104 __ Sxtw(integer_exponent, integer_exponent); | 4104 __ Sxtw(integer_exponent, integer_exponent); |
| 4105 MathPowStub stub(isolate(), MathPowStub::INTEGER); | 4105 MathPowStub stub(isolate(), MathPowStub::INTEGER); |
| 4106 __ CallStub(&stub); | 4106 __ CallStub(&stub); |
| 4107 } else { | 4107 } else { |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4654 HValue* value = instr->hydrogen()->value(); | 4654 HValue* value = instr->hydrogen()->value(); |
| 4655 NumberUntagDMode mode = value->representation().IsSmi() | 4655 NumberUntagDMode mode = value->representation().IsSmi() |
| 4656 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; | 4656 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; |
| 4657 | 4657 |
| 4658 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { | 4658 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { |
| 4659 __ JumpIfSmi(input, &load_smi); | 4659 __ JumpIfSmi(input, &load_smi); |
| 4660 | 4660 |
| 4661 Label convert_undefined; | 4661 Label convert_undefined; |
| 4662 | 4662 |
| 4663 // Heap number map check. | 4663 // Heap number map check. |
| 4664 __ Ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | |
| 4665 if (can_convert_undefined_to_nan) { | 4664 if (can_convert_undefined_to_nan) { |
| 4666 __ JumpIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex, | 4665 __ JumpIfNotHeapNumber(input, &convert_undefined); |
| 4667 &convert_undefined); | |
| 4668 } else { | 4666 } else { |
| 4669 DeoptimizeIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex, instr); | 4667 DeoptimizeIfNotHeapNumber(input, instr); |
| 4670 } | 4668 } |
| 4671 | 4669 |
| 4672 // Load heap number. | 4670 // Load heap number. |
| 4673 __ Ldr(result, FieldMemOperand(input, HeapNumber::kValueOffset)); | 4671 __ Ldr(result, FieldMemOperand(input, HeapNumber::kValueOffset)); |
| 4674 if (instr->hydrogen()->deoptimize_on_minus_zero()) { | 4672 if (instr->hydrogen()->deoptimize_on_minus_zero()) { |
| 4675 DeoptimizeIfMinusZero(result, instr); | 4673 DeoptimizeIfMinusZero(result, instr); |
| 4676 } | 4674 } |
| 4677 __ B(&done); | 4675 __ B(&done); |
| 4678 | 4676 |
| 4679 if (can_convert_undefined_to_nan) { | 4677 if (can_convert_undefined_to_nan) { |
| (...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5589 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, | 5587 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, |
| 5590 LOperand* value, | 5588 LOperand* value, |
| 5591 LOperand* temp1, | 5589 LOperand* temp1, |
| 5592 LOperand* temp2) { | 5590 LOperand* temp2) { |
| 5593 Register input = ToRegister(value); | 5591 Register input = ToRegister(value); |
| 5594 Register scratch1 = ToRegister(temp1); | 5592 Register scratch1 = ToRegister(temp1); |
| 5595 DoubleRegister dbl_scratch1 = double_scratch(); | 5593 DoubleRegister dbl_scratch1 = double_scratch(); |
| 5596 | 5594 |
| 5597 Label done; | 5595 Label done; |
| 5598 | 5596 |
| 5599 // Load heap object map. | |
| 5600 __ Ldr(scratch1, FieldMemOperand(input, HeapObject::kMapOffset)); | |
| 5601 | |
| 5602 if (instr->truncating()) { | 5597 if (instr->truncating()) { |
| 5603 Register output = ToRegister(instr->result()); | 5598 Register output = ToRegister(instr->result()); |
| 5604 Label check_bools; | 5599 Label check_bools; |
| 5605 | 5600 |
| 5606 // If it's not a heap number, jump to undefined check. | 5601 // If it's not a heap number, jump to undefined check. |
| 5607 __ JumpIfNotRoot(scratch1, Heap::kHeapNumberMapRootIndex, &check_bools); | 5602 __ JumpIfNotHeapNumber(input, &check_bools); |
| 5608 | 5603 |
| 5609 // A heap number: load value and convert to int32 using truncating function. | 5604 // A heap number: load value and convert to int32 using truncating function. |
| 5610 __ TruncateHeapNumberToI(output, input); | 5605 __ TruncateHeapNumberToI(output, input); |
| 5611 __ B(&done); | 5606 __ B(&done); |
| 5612 | 5607 |
| 5613 __ Bind(&check_bools); | 5608 __ Bind(&check_bools); |
| 5614 | 5609 |
| 5615 Register true_root = output; | 5610 Register true_root = output; |
| 5616 Register false_root = scratch1; | 5611 Register false_root = scratch1; |
| 5617 __ LoadTrueFalseRoots(true_root, false_root); | 5612 __ LoadTrueFalseRoots(true_root, false_root); |
| 5618 __ Cmp(input, true_root); | 5613 __ Cmp(input, true_root); |
| 5619 __ Cset(output, eq); | 5614 __ Cset(output, eq); |
| 5620 __ Ccmp(input, false_root, ZFlag, ne); | 5615 __ Ccmp(input, false_root, ZFlag, ne); |
| 5621 __ B(eq, &done); | 5616 __ B(eq, &done); |
| 5622 | 5617 |
| 5623 // Output contains zero, undefined is converted to zero for truncating | 5618 // Output contains zero, undefined is converted to zero for truncating |
| 5624 // conversions. | 5619 // conversions. |
| 5625 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr); | 5620 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr); |
| 5626 } else { | 5621 } else { |
| 5627 Register output = ToRegister32(instr->result()); | 5622 Register output = ToRegister32(instr->result()); |
| 5628 DoubleRegister dbl_scratch2 = ToDoubleRegister(temp2); | 5623 DoubleRegister dbl_scratch2 = ToDoubleRegister(temp2); |
| 5629 | 5624 |
| 5630 __ RecordComment("Deferred TaggedToI: not a heap number"); | 5625 __ RecordComment("Deferred TaggedToI: not a heap number"); |
| 5631 DeoptimizeIfNotRoot(scratch1, Heap::kHeapNumberMapRootIndex, instr); | 5626 DeoptimizeIfNotHeapNumber(input, instr); |
| 5632 | 5627 |
| 5633 // A heap number: load value and convert to int32 using non-truncating | 5628 // A heap number: load value and convert to int32 using non-truncating |
| 5634 // function. If the result is out of range, branch to deoptimize. | 5629 // function. If the result is out of range, branch to deoptimize. |
| 5635 __ Ldr(dbl_scratch1, FieldMemOperand(input, HeapNumber::kValueOffset)); | 5630 __ Ldr(dbl_scratch1, FieldMemOperand(input, HeapNumber::kValueOffset)); |
| 5636 __ TryRepresentDoubleAsInt32(output, dbl_scratch1, dbl_scratch2); | 5631 __ TryRepresentDoubleAsInt32(output, dbl_scratch1, dbl_scratch2); |
| 5637 __ RecordComment("Deferred TaggedToI: lost precision or NaN"); | 5632 __ RecordComment("Deferred TaggedToI: lost precision or NaN"); |
| 5638 DeoptimizeIf(ne, instr); | 5633 DeoptimizeIf(ne, instr); |
| 5639 | 5634 |
| 5640 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 5635 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 5641 __ Cmp(output, 0); | 5636 __ Cmp(output, 0); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5806 | 5801 |
| 5807 | 5802 |
| 5808 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 5803 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
| 5809 Handle<String> type_name = instr->type_literal(); | 5804 Handle<String> type_name = instr->type_literal(); |
| 5810 Label* true_label = instr->TrueLabel(chunk_); | 5805 Label* true_label = instr->TrueLabel(chunk_); |
| 5811 Label* false_label = instr->FalseLabel(chunk_); | 5806 Label* false_label = instr->FalseLabel(chunk_); |
| 5812 Register value = ToRegister(instr->value()); | 5807 Register value = ToRegister(instr->value()); |
| 5813 | 5808 |
| 5814 Factory* factory = isolate()->factory(); | 5809 Factory* factory = isolate()->factory(); |
| 5815 if (String::Equals(type_name, factory->number_string())) { | 5810 if (String::Equals(type_name, factory->number_string())) { |
| 5816 DCHECK(instr->temp1() != NULL); | 5811 __ JumpIfSmi(value, true_label); |
| 5817 Register map = ToRegister(instr->temp1()); | |
| 5818 | 5812 |
| 5819 __ JumpIfSmi(value, true_label); | 5813 int true_block = instr->TrueDestination(chunk_); |
| 5820 __ Ldr(map, FieldMemOperand(value, HeapObject::kMapOffset)); | 5814 int false_block = instr->FalseDestination(chunk_); |
| 5821 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 5815 int next_block = GetNextEmittedBlock(); |
| 5822 EmitBranch(instr, eq); | 5816 |
| 5817 if (true_block == false_block) { |
| 5818 EmitGoto(true_block); |
| 5819 } else if (true_block == next_block) { |
| 5820 __ JumpIfNotHeapNumber(value, chunk_->GetAssemblyLabel(false_block)); |
| 5821 } else { |
| 5822 __ JumpIfHeapNumber(value, chunk_->GetAssemblyLabel(true_block)); |
| 5823 if (false_block != next_block) { |
| 5824 __ B(chunk_->GetAssemblyLabel(false_block)); |
| 5825 } |
| 5826 } |
| 5823 | 5827 |
| 5824 } else if (String::Equals(type_name, factory->string_string())) { | 5828 } else if (String::Equals(type_name, factory->string_string())) { |
| 5825 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL)); | 5829 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL)); |
| 5826 Register map = ToRegister(instr->temp1()); | 5830 Register map = ToRegister(instr->temp1()); |
| 5827 Register scratch = ToRegister(instr->temp2()); | 5831 Register scratch = ToRegister(instr->temp2()); |
| 5828 | 5832 |
| 5829 __ JumpIfSmi(value, false_label); | 5833 __ JumpIfSmi(value, false_label); |
| 5830 __ JumpIfObjectType( | 5834 __ JumpIfObjectType( |
| 5831 value, map, scratch, FIRST_NONSTRING_TYPE, false_label, ge); | 5835 value, map, scratch, FIRST_NONSTRING_TYPE, false_label, ge); |
| 5832 __ Ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); | 5836 __ Ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6035 Handle<ScopeInfo> scope_info = instr->scope_info(); | 6039 Handle<ScopeInfo> scope_info = instr->scope_info(); |
| 6036 __ Push(scope_info); | 6040 __ Push(scope_info); |
| 6037 __ Push(ToRegister(instr->function())); | 6041 __ Push(ToRegister(instr->function())); |
| 6038 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6042 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 6039 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6043 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 6040 } | 6044 } |
| 6041 | 6045 |
| 6042 | 6046 |
| 6043 | 6047 |
| 6044 } } // namespace v8::internal | 6048 } } // namespace v8::internal |
| OLD | NEW |