| 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 |