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 |