OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2441 Label done, fail; | 2441 Label done, fail; |
2442 __ lw(scratch, FieldMemOperand(result, HeapObject::kMapOffset)); | 2442 __ lw(scratch, FieldMemOperand(result, HeapObject::kMapOffset)); |
2443 __ LoadRoot(at, Heap::kFixedArrayMapRootIndex); | 2443 __ LoadRoot(at, Heap::kFixedArrayMapRootIndex); |
2444 __ Branch(USE_DELAY_SLOT, &done, eq, scratch, Operand(at)); | 2444 __ Branch(USE_DELAY_SLOT, &done, eq, scratch, Operand(at)); |
2445 __ LoadRoot(at, Heap::kFixedCOWArrayMapRootIndex); // In the delay slot. | 2445 __ LoadRoot(at, Heap::kFixedCOWArrayMapRootIndex); // In the delay slot. |
2446 __ Branch(&done, eq, scratch, Operand(at)); | 2446 __ Branch(&done, eq, scratch, Operand(at)); |
2447 // |scratch| still contains |input|'s map. | 2447 // |scratch| still contains |input|'s map. |
2448 __ lbu(scratch, FieldMemOperand(scratch, Map::kBitField2Offset)); | 2448 __ lbu(scratch, FieldMemOperand(scratch, Map::kBitField2Offset)); |
2449 __ Ext(scratch, scratch, Map::kElementsKindShift, | 2449 __ Ext(scratch, scratch, Map::kElementsKindShift, |
2450 Map::kElementsKindBitCount); | 2450 Map::kElementsKindBitCount); |
2451 __ Branch(&fail, lt, scratch, | 2451 __ Branch(&done, eq, scratch, |
2452 Operand(GetInitialFastElementsKind())); | 2452 Operand(FAST_ELEMENTS)); |
2453 __ Branch(&done, le, scratch, | |
2454 Operand(TERMINAL_FAST_ELEMENTS_KIND)); | |
2455 __ Branch(&fail, lt, scratch, | 2453 __ Branch(&fail, lt, scratch, |
2456 Operand(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); | 2454 Operand(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); |
2457 __ Branch(&done, le, scratch, | 2455 __ Branch(&done, le, scratch, |
2458 Operand(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); | 2456 Operand(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); |
2459 __ bind(&fail); | 2457 __ bind(&fail); |
2460 __ Abort("Check for fast or external elements failed."); | 2458 __ Abort("Check for fast or external elements failed."); |
2461 __ bind(&done); | 2459 __ bind(&done); |
2462 } | 2460 } |
2463 } | 2461 } |
2464 | 2462 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2541 Operand(((constant_key + instr->additional_index()) << shift_size) + | 2539 Operand(((constant_key + instr->additional_index()) << shift_size) + |
2542 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 2540 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
2543 } else { | 2541 } else { |
2544 __ sll(scratch, key, shift_size); | 2542 __ sll(scratch, key, shift_size); |
2545 __ Addu(elements, elements, Operand(scratch)); | 2543 __ Addu(elements, elements, Operand(scratch)); |
2546 __ Addu(elements, elements, | 2544 __ Addu(elements, elements, |
2547 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) + | 2545 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) + |
2548 (instr->additional_index() << shift_size))); | 2546 (instr->additional_index() << shift_size))); |
2549 } | 2547 } |
2550 | 2548 |
2551 if (instr->hydrogen()->RequiresHoleCheck()) { | 2549 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
2552 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | 2550 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); |
2553 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); | |
2554 } | |
2555 | 2551 |
2556 __ ldc1(result, MemOperand(elements)); | 2552 __ ldc1(result, MemOperand(elements)); |
2557 } | 2553 } |
2558 | 2554 |
2559 | 2555 |
2560 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | 2556 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
2561 LLoadKeyedSpecializedArrayElement* instr) { | 2557 LLoadKeyedSpecializedArrayElement* instr) { |
2562 Register external_pointer = ToRegister(instr->external_pointer()); | 2558 Register external_pointer = ToRegister(instr->external_pointer()); |
2563 Register key = no_reg; | 2559 Register key = no_reg; |
2564 ElementsKind elements_kind = instr->elements_kind(); | 2560 ElementsKind elements_kind = instr->elements_kind(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2633 // TODO(danno): we could be more clever here, perhaps having a special | 2629 // TODO(danno): we could be more clever here, perhaps having a special |
2634 // version of the stub that detects if the overflow case actually | 2630 // version of the stub that detects if the overflow case actually |
2635 // happens, and generate code that returns a double rather than int. | 2631 // happens, and generate code that returns a double rather than int. |
2636 DeoptimizeIf(Ugreater_equal, instr->environment(), | 2632 DeoptimizeIf(Ugreater_equal, instr->environment(), |
2637 result, Operand(0x80000000)); | 2633 result, Operand(0x80000000)); |
2638 break; | 2634 break; |
2639 case EXTERNAL_FLOAT_ELEMENTS: | 2635 case EXTERNAL_FLOAT_ELEMENTS: |
2640 case EXTERNAL_DOUBLE_ELEMENTS: | 2636 case EXTERNAL_DOUBLE_ELEMENTS: |
2641 case FAST_DOUBLE_ELEMENTS: | 2637 case FAST_DOUBLE_ELEMENTS: |
2642 case FAST_ELEMENTS: | 2638 case FAST_ELEMENTS: |
2643 case FAST_SMI_ELEMENTS: | 2639 case FAST_SMI_ONLY_ELEMENTS: |
2644 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
2645 case FAST_HOLEY_ELEMENTS: | |
2646 case FAST_HOLEY_SMI_ELEMENTS: | |
2647 case DICTIONARY_ELEMENTS: | 2640 case DICTIONARY_ELEMENTS: |
2648 case NON_STRICT_ARGUMENTS_ELEMENTS: | 2641 case NON_STRICT_ARGUMENTS_ELEMENTS: |
2649 UNREACHABLE(); | 2642 UNREACHABLE(); |
2650 break; | 2643 break; |
2651 } | 2644 } |
2652 } | 2645 } |
2653 } | 2646 } |
2654 | 2647 |
2655 | 2648 |
2656 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 2649 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3669 __ sh(value, mem_operand); | 3662 __ sh(value, mem_operand); |
3670 break; | 3663 break; |
3671 case EXTERNAL_INT_ELEMENTS: | 3664 case EXTERNAL_INT_ELEMENTS: |
3672 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3665 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3673 __ sw(value, mem_operand); | 3666 __ sw(value, mem_operand); |
3674 break; | 3667 break; |
3675 case EXTERNAL_FLOAT_ELEMENTS: | 3668 case EXTERNAL_FLOAT_ELEMENTS: |
3676 case EXTERNAL_DOUBLE_ELEMENTS: | 3669 case EXTERNAL_DOUBLE_ELEMENTS: |
3677 case FAST_DOUBLE_ELEMENTS: | 3670 case FAST_DOUBLE_ELEMENTS: |
3678 case FAST_ELEMENTS: | 3671 case FAST_ELEMENTS: |
3679 case FAST_SMI_ELEMENTS: | 3672 case FAST_SMI_ONLY_ELEMENTS: |
3680 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
3681 case FAST_HOLEY_ELEMENTS: | |
3682 case FAST_HOLEY_SMI_ELEMENTS: | |
3683 case DICTIONARY_ELEMENTS: | 3673 case DICTIONARY_ELEMENTS: |
3684 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3674 case NON_STRICT_ARGUMENTS_ELEMENTS: |
3685 UNREACHABLE(); | 3675 UNREACHABLE(); |
3686 break; | 3676 break; |
3687 } | 3677 } |
3688 } | 3678 } |
3689 } | 3679 } |
3690 | 3680 |
3691 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 3681 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
3692 ASSERT(ToRegister(instr->object()).is(a2)); | 3682 ASSERT(ToRegister(instr->object()).is(a2)); |
(...skipping 17 matching lines...) Expand all Loading... |
3710 ElementsKind from_kind = from_map->elements_kind(); | 3700 ElementsKind from_kind = from_map->elements_kind(); |
3711 ElementsKind to_kind = to_map->elements_kind(); | 3701 ElementsKind to_kind = to_map->elements_kind(); |
3712 | 3702 |
3713 __ mov(ToRegister(instr->result()), object_reg); | 3703 __ mov(ToRegister(instr->result()), object_reg); |
3714 | 3704 |
3715 Label not_applicable; | 3705 Label not_applicable; |
3716 __ lw(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset)); | 3706 __ lw(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset)); |
3717 __ Branch(¬_applicable, ne, scratch, Operand(from_map)); | 3707 __ Branch(¬_applicable, ne, scratch, Operand(from_map)); |
3718 | 3708 |
3719 __ li(new_map_reg, Operand(to_map)); | 3709 __ li(new_map_reg, Operand(to_map)); |
3720 if (IsFastSmiElementsKind(from_kind) && IsFastObjectElementsKind(to_kind)) { | 3710 if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { |
3721 __ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); | 3711 __ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); |
3722 // Write barrier. | 3712 // Write barrier. |
3723 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, | 3713 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, |
3724 scratch, kRAHasBeenSaved, kDontSaveFPRegs); | 3714 scratch, kRAHasBeenSaved, kDontSaveFPRegs); |
3725 } else if (IsFastSmiElementsKind(from_kind) && | 3715 } else if (from_kind == FAST_SMI_ONLY_ELEMENTS && |
3726 IsFastDoubleElementsKind(to_kind)) { | 3716 to_kind == FAST_DOUBLE_ELEMENTS) { |
3727 Register fixed_object_reg = ToRegister(instr->temp_reg()); | 3717 Register fixed_object_reg = ToRegister(instr->temp_reg()); |
3728 ASSERT(fixed_object_reg.is(a2)); | 3718 ASSERT(fixed_object_reg.is(a2)); |
3729 ASSERT(new_map_reg.is(a3)); | 3719 ASSERT(new_map_reg.is(a3)); |
3730 __ mov(fixed_object_reg, object_reg); | 3720 __ mov(fixed_object_reg, object_reg); |
3731 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), | 3721 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), |
3732 RelocInfo::CODE_TARGET, instr); | 3722 RelocInfo::CODE_TARGET, instr); |
3733 } else if (IsFastDoubleElementsKind(from_kind) && | 3723 } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { |
3734 IsFastObjectElementsKind(to_kind)) { | |
3735 Register fixed_object_reg = ToRegister(instr->temp_reg()); | 3724 Register fixed_object_reg = ToRegister(instr->temp_reg()); |
3736 ASSERT(fixed_object_reg.is(a2)); | 3725 ASSERT(fixed_object_reg.is(a2)); |
3737 ASSERT(new_map_reg.is(a3)); | 3726 ASSERT(new_map_reg.is(a3)); |
3738 __ mov(fixed_object_reg, object_reg); | 3727 __ mov(fixed_object_reg, object_reg); |
3739 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), | 3728 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), |
3740 RelocInfo::CODE_TARGET, instr); | 3729 RelocInfo::CODE_TARGET, instr); |
3741 } else { | 3730 } else { |
3742 UNREACHABLE(); | 3731 UNREACHABLE(); |
3743 } | 3732 } |
3744 __ bind(¬_applicable); | 3733 __ bind(¬_applicable); |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4479 } | 4468 } |
4480 | 4469 |
4481 | 4470 |
4482 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 4471 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
4483 Heap* heap = isolate()->heap(); | 4472 Heap* heap = isolate()->heap(); |
4484 ElementsKind boilerplate_elements_kind = | 4473 ElementsKind boilerplate_elements_kind = |
4485 instr->hydrogen()->boilerplate_elements_kind(); | 4474 instr->hydrogen()->boilerplate_elements_kind(); |
4486 | 4475 |
4487 // Deopt if the array literal boilerplate ElementsKind is of a type different | 4476 // Deopt if the array literal boilerplate ElementsKind is of a type different |
4488 // than the expected one. The check isn't necessary if the boilerplate has | 4477 // than the expected one. The check isn't necessary if the boilerplate has |
4489 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. | 4478 // already been converted to FAST_ELEMENTS. |
4490 if (CanTransitionToMoreGeneralFastElementsKind( | 4479 if (boilerplate_elements_kind != FAST_ELEMENTS) { |
4491 boilerplate_elements_kind, true)) { | |
4492 __ LoadHeapObject(a1, instr->hydrogen()->boilerplate_object()); | 4480 __ LoadHeapObject(a1, instr->hydrogen()->boilerplate_object()); |
4493 // Load map into a2. | 4481 // Load map into a2. |
4494 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); | 4482 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); |
4495 // Load the map's "bit field 2". | 4483 // Load the map's "bit field 2". |
4496 __ lbu(a2, FieldMemOperand(a2, Map::kBitField2Offset)); | 4484 __ lbu(a2, FieldMemOperand(a2, Map::kBitField2Offset)); |
4497 // Retrieve elements_kind from bit field 2. | 4485 // Retrieve elements_kind from bit field 2. |
4498 __ Ext(a2, a2, Map::kElementsKindShift, Map::kElementsKindBitCount); | 4486 __ Ext(a2, a2, Map::kElementsKindShift, Map::kElementsKindBitCount); |
4499 DeoptimizeIf(ne, | 4487 DeoptimizeIf(ne, |
4500 instr->environment(), | 4488 instr->environment(), |
4501 a2, | 4489 a2, |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4634 } | 4622 } |
4635 } | 4623 } |
4636 } | 4624 } |
4637 | 4625 |
4638 | 4626 |
4639 void LCodeGen::DoFastLiteral(LFastLiteral* instr) { | 4627 void LCodeGen::DoFastLiteral(LFastLiteral* instr) { |
4640 int size = instr->hydrogen()->total_size(); | 4628 int size = instr->hydrogen()->total_size(); |
4641 ElementsKind boilerplate_elements_kind = | 4629 ElementsKind boilerplate_elements_kind = |
4642 instr->hydrogen()->boilerplate()->GetElementsKind(); | 4630 instr->hydrogen()->boilerplate()->GetElementsKind(); |
4643 | 4631 |
4644 // Deopt if the array literal boilerplate ElementsKind is of a type different | 4632 // Deopt if the literal boilerplate ElementsKind is of a type different than |
4645 // than the expected one. The check isn't necessary if the boilerplate has | 4633 // the expected one. The check isn't necessary if the boilerplate has already |
4646 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. | 4634 // been converted to FAST_ELEMENTS. |
4647 if (CanTransitionToMoreGeneralFastElementsKind( | 4635 if (boilerplate_elements_kind != FAST_ELEMENTS) { |
4648 boilerplate_elements_kind, true)) { | |
4649 __ LoadHeapObject(a1, instr->hydrogen()->boilerplate()); | 4636 __ LoadHeapObject(a1, instr->hydrogen()->boilerplate()); |
4650 // Load map into a2. | 4637 // Load map into a2. |
4651 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); | 4638 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); |
4652 // Load the map's "bit field 2". | 4639 // Load the map's "bit field 2". |
4653 __ lbu(a2, FieldMemOperand(a2, Map::kBitField2Offset)); | 4640 __ lbu(a2, FieldMemOperand(a2, Map::kBitField2Offset)); |
4654 // Retrieve elements_kind from bit field 2. | 4641 // Retrieve elements_kind from bit field 2. |
4655 __ Ext(a2, a2, Map::kElementsKindShift, Map::kElementsKindBitCount); | 4642 __ Ext(a2, a2, Map::kElementsKindShift, Map::kElementsKindBitCount); |
4656 DeoptimizeIf(ne, instr->environment(), a2, | 4643 DeoptimizeIf(ne, instr->environment(), a2, |
4657 Operand(boilerplate_elements_kind)); | 4644 Operand(boilerplate_elements_kind)); |
4658 } | 4645 } |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5163 __ Subu(scratch, result, scratch); | 5150 __ Subu(scratch, result, scratch); |
5164 __ lw(result, FieldMemOperand(scratch, | 5151 __ lw(result, FieldMemOperand(scratch, |
5165 FixedArray::kHeaderSize - kPointerSize)); | 5152 FixedArray::kHeaderSize - kPointerSize)); |
5166 __ bind(&done); | 5153 __ bind(&done); |
5167 } | 5154 } |
5168 | 5155 |
5169 | 5156 |
5170 #undef __ | 5157 #undef __ |
5171 | 5158 |
5172 } } // namespace v8::internal | 5159 } } // namespace v8::internal |
OLD | NEW |