OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 // RA: return address. | 686 // RA: return address. |
687 // A1: Array length as Smi (must be preserved). | 687 // A1: Array length as Smi (must be preserved). |
688 // A0: array element type (either NULL or an instantiated type). | 688 // A0: array element type (either NULL or an instantiated type). |
689 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved. | 689 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved. |
690 // The newly allocated object is returned in V0. | 690 // The newly allocated object is returned in V0. |
691 void StubCode::GeneratePatchableAllocateArrayStub(Assembler* assembler, | 691 void StubCode::GeneratePatchableAllocateArrayStub(Assembler* assembler, |
692 uword* entry_patch_offset, uword* patch_code_pc_offset) { | 692 uword* entry_patch_offset, uword* patch_code_pc_offset) { |
693 __ Comment("AllocateArrayStub"); | 693 __ Comment("AllocateArrayStub"); |
694 *entry_patch_offset = assembler->CodeSize(); | 694 *entry_patch_offset = assembler->CodeSize(); |
695 Label slow_case; | 695 Label slow_case; |
| 696 Isolate* isolate = Isolate::Current(); |
| 697 const Class& cls = Class::Handle(isolate->object_store()->array_class()); |
| 698 ASSERT(!cls.IsNull()); |
696 | 699 |
697 // Compute the size to be allocated, it is based on the array length | 700 // Compute the size to be allocated, it is based on the array length |
698 // and is computed as: | 701 // and is computed as: |
699 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). | 702 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). |
700 __ mov(T3, A1); // Array length. | 703 __ mov(T3, A1); // Array length. |
701 | 704 |
702 // Check that length is a positive Smi. | 705 // Check that length is a positive Smi. |
703 __ andi(CMPRES1, T3, Immediate(kSmiTagMask)); | 706 __ andi(CMPRES1, T3, Immediate(kSmiTagMask)); |
704 __ bne(CMPRES1, ZR, &slow_case); | 707 if (FLAG_use_slow_path || cls.trace_allocation()) { |
| 708 __ b(&slow_case); |
| 709 } else { |
| 710 __ bne(CMPRES1, ZR, &slow_case); |
| 711 } |
705 __ bltz(T3, &slow_case); | 712 __ bltz(T3, &slow_case); |
706 | 713 |
707 // Check for maximum allowed length. | 714 // Check for maximum allowed length. |
708 const intptr_t max_len = | 715 const intptr_t max_len = |
709 reinterpret_cast<int32_t>(Smi::New(Array::kMaxElements)); | 716 reinterpret_cast<int32_t>(Smi::New(Array::kMaxElements)); |
710 __ BranchUnsignedGreater(T3, Immediate(max_len), &slow_case); | 717 __ BranchUnsignedGreater(T3, Immediate(max_len), &slow_case); |
711 | 718 |
712 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 719 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
713 __ LoadImmediate(T2, fixed_size); | 720 __ LoadImmediate(T2, fixed_size); |
714 __ sll(T3, T3, 1); // T3 is a Smi. | 721 __ sll(T3, T3, 1); // T3 is a Smi. |
715 __ addu(T2, T2, T3); | 722 __ addu(T2, T2, T3); |
716 ASSERT(kSmiTagShift == 1); | 723 ASSERT(kSmiTagShift == 1); |
717 __ LoadImmediate(T3, ~(kObjectAlignment - 1)); | 724 __ LoadImmediate(T3, ~(kObjectAlignment - 1)); |
718 __ and_(T2, T2, T3); | 725 __ and_(T2, T2, T3); |
719 | 726 |
720 // T2: Allocation size. | 727 // T2: Allocation size. |
721 | 728 |
722 Isolate* isolate = Isolate::Current(); | |
723 Heap* heap = isolate->heap(); | 729 Heap* heap = isolate->heap(); |
724 const intptr_t cid = kArrayCid; | 730 const intptr_t cid = kArrayCid; |
725 Heap::Space space = heap->SpaceForAllocation(cid); | 731 Heap::Space space = heap->SpaceForAllocation(cid); |
726 __ LoadImmediate(T3, heap->TopAddress(space)); | 732 __ LoadImmediate(T3, heap->TopAddress(space)); |
727 __ lw(T0, Address(T3, 0)); // Potential new object start. | 733 __ lw(T0, Address(T3, 0)); // Potential new object start. |
728 | 734 |
729 __ addu(T1, T0, T2); // Potential next object start. | 735 __ addu(T1, T0, T2); // Potential next object start. |
730 __ BranchUnsignedLess(T1, T0, &slow_case); // Branch on unsigned overflow. | 736 __ BranchUnsignedLess(T1, T0, &slow_case); // Branch on unsigned overflow. |
731 | 737 |
732 // Check if the allocation fits into the remaining space. | 738 // Check if the allocation fits into the remaining space. |
(...skipping 1580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2313 // Result: | 2319 // Result: |
2314 // T1: entry point. | 2320 // T1: entry point. |
2315 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2321 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2316 EmitMegamorphicLookup(assembler, T0, T1, T1); | 2322 EmitMegamorphicLookup(assembler, T0, T1, T1); |
2317 __ Ret(); | 2323 __ Ret(); |
2318 } | 2324 } |
2319 | 2325 |
2320 } // namespace dart | 2326 } // namespace dart |
2321 | 2327 |
2322 #endif // defined TARGET_ARCH_MIPS | 2328 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |