Chromium Code Reviews| Index: runtime/vm/assembler_x64.cc |
| =================================================================== |
| --- runtime/vm/assembler_x64.cc (revision 38897) |
| +++ runtime/vm/assembler_x64.cc (working copy) |
| @@ -3119,28 +3119,43 @@ |
| } |
| -void Assembler::UpdateAllocationStats(intptr_t cid, |
| - Heap::Space space) { |
| +void Assembler::ComputeCounterAddressesForCid(intptr_t cid, |
| + Heap::Space space, |
| + Address* count_address, |
| + Address* size_address) { |
| + ASSERT(cid < kNumPredefinedCids); |
| Register temp_reg = TMP; |
| - ASSERT(cid > 0); |
| Isolate* isolate = Isolate::Current(); |
| ClassTable* class_table = isolate->class_table(); |
| - if (cid < kNumPredefinedCids) { |
| const uword class_heap_stats_table_address = |
| class_table->PredefinedClassHeapStatsTableAddress(); |
| const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| const uword count_field_offset = (space == Heap::kNew) ? |
| ClassHeapStats::allocated_since_gc_new_space_offset() : |
| ClassHeapStats::allocated_since_gc_old_space_offset(); |
| + const uword size_field_offset = (space == Heap::kNew) ? |
| + ClassHeapStats::allocated_size_since_gc_new_space_offset() : |
|
srdjan
2014/08/11 21:42:34
This and above and below should have 4 spaces inde
Florian Schneider
2014/08/13 14:56:12
Done.
Florian Schneider
2014/08/13 14:56:12
Done.
|
| + ClassHeapStats::allocated_size_since_gc_old_space_offset(); |
| movq(temp_reg, Immediate(class_heap_stats_table_address + class_offset)); |
| - const Address& count_address = Address(temp_reg, count_field_offset); |
| + *count_address = Address(temp_reg, count_field_offset); |
| + *size_address = Address(temp_reg, size_field_offset); |
| +} |
| + |
| + |
| +void Assembler::UpdateAllocationStats(intptr_t cid, |
| + Heap::Space space) { |
| + ASSERT(cid > 0); |
| + if (cid < kNumPredefinedCids) { |
| + Address count_address(kNoRegister, 0), size_address(kNoRegister, 0); |
| + ComputeCounterAddressesForCid(cid, space, &count_address, &size_address); |
| incq(count_address); |
| } else { |
| - ASSERT(temp_reg != kNoRegister); |
| + Register temp_reg = TMP; |
| const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| const uword count_field_offset = (space == Heap::kNew) ? |
| ClassHeapStats::allocated_since_gc_new_space_offset() : |
| ClassHeapStats::allocated_since_gc_old_space_offset(); |
| + ClassTable* class_table = Isolate::Current()->class_table(); |
| movq(temp_reg, Immediate(class_table->ClassStatsTableAddress())); |
| movq(temp_reg, Address(temp_reg, 0)); |
| incq(Address(temp_reg, class_offset + count_field_offset)); |
| @@ -3151,42 +3166,27 @@ |
| void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, |
| Register size_reg, |
| Heap::Space space) { |
| - Register temp_reg = TMP; |
| ASSERT(cid > 0); |
| - Isolate* isolate = Isolate::Current(); |
| - ClassTable* class_table = isolate->class_table(); |
| - if (cid < kNumPredefinedCids) { |
| - const uword class_heap_stats_table_address = |
| - class_table->PredefinedClassHeapStatsTableAddress(); |
| - const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| - const uword count_field_offset = (space == Heap::kNew) ? |
| - ClassHeapStats::allocated_since_gc_new_space_offset() : |
| - ClassHeapStats::allocated_since_gc_old_space_offset(); |
| - const uword size_field_offset = (space == Heap::kNew) ? |
| - ClassHeapStats::allocated_size_since_gc_new_space_offset() : |
| - ClassHeapStats::allocated_size_since_gc_old_space_offset(); |
| - movq(temp_reg, Immediate(class_heap_stats_table_address + class_offset)); |
| - const Address& count_address = Address(temp_reg, count_field_offset); |
| - const Address& size_address = Address(temp_reg, size_field_offset); |
| - incq(count_address); |
| - addq(size_address, size_reg); |
| - } else { |
| - ASSERT(temp_reg != kNoRegister); |
| - const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| - const uword count_field_offset = (space == Heap::kNew) ? |
| - ClassHeapStats::allocated_since_gc_new_space_offset() : |
| - ClassHeapStats::allocated_since_gc_old_space_offset(); |
| - const uword size_field_offset = (space == Heap::kNew) ? |
| - ClassHeapStats::allocated_size_since_gc_new_space_offset() : |
| - ClassHeapStats::allocated_size_since_gc_old_space_offset(); |
| - movq(temp_reg, Immediate(class_table->ClassStatsTableAddress())); |
| - movq(temp_reg, Address(temp_reg, 0)); |
| - incq(Address(temp_reg, class_offset + count_field_offset)); |
| - addq(Address(temp_reg, class_offset + size_field_offset), size_reg); |
| - } |
| + ASSERT(cid < kNumPredefinedCids); |
| + Address count_address(kNoRegister, 0), size_address(kNoRegister, 0); |
| + ComputeCounterAddressesForCid(cid, space, &count_address, &size_address); |
| + incq(count_address); |
| + addq(size_address, size_reg); |
| } |
| +void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, |
| + intptr_t size_in_bytes, |
| + Heap::Space space) { |
| + ASSERT(cid > 0); |
| + ASSERT(cid < kNumPredefinedCids); |
| + Address count_address(kNoRegister, 0), size_address(kNoRegister, 0); |
| + ComputeCounterAddressesForCid(cid, space, &count_address, &size_address); |
| + incq(count_address); |
| + addq(size_address, Immediate(size_in_bytes)); |
| +} |
| + |
| + |
| void Assembler::TryAllocate(const Class& cls, |
| Label* failure, |
| bool near_jump, |
| @@ -3222,6 +3222,49 @@ |
| } |
| +void Assembler::TryAllocateArray(intptr_t cid, |
| + intptr_t instance_size, |
| + Label* failure, |
| + bool near_jump, |
| + Register instance, |
| + Register end_address) { |
| + ASSERT(failure != NULL); |
| + if (FLAG_inline_alloc) { |
| + Isolate* isolate = Isolate::Current(); |
| + Heap* heap = isolate->heap(); |
| + |
| + movq(instance, Immediate(heap->TopAddress())); |
| + movq(instance, Address(instance, 0)); |
| + movq(end_address, RAX); |
| + |
| + addq(end_address, Immediate(instance_size)); |
| + j(CARRY, failure); |
| + |
| + // Check if the allocation fits into the remaining space. |
| + // instance: potential new object start. |
| + // end_address: potential next object start. |
| + movq(TMP, Immediate(heap->EndAddress())); |
| + cmpq(end_address, Address(TMP, 0)); |
| + j(ABOVE_EQUAL, failure); |
| + |
| + // Successfully allocated the object(s), now update top to point to |
| + // next object start and initialize the object. |
| + movq(TMP, Immediate(heap->TopAddress())); |
| + movq(Address(TMP, 0), end_address); |
| + addq(instance, Immediate(kHeapObjectTag)); |
| + UpdateAllocationStatsWithSize(kArrayCid, instance_size); |
| + |
| + // Initialize the tags. |
| + // instance: new object start as a tagged pointer. |
| + uword tags = 0; |
| + tags = RawObject::ClassIdTag::update(cid, tags); |
| + tags = RawObject::SizeTag::update(instance_size, tags); |
| + movq(FieldAddress(instance, Array::tags_offset()), Immediate(tags)); |
| + } else { |
| + jmp(failure); |
| + } |
| +} |
| + |
| void Assembler::Align(int alignment, intptr_t offset) { |
| ASSERT(Utils::IsPowerOfTwo(alignment)); |
| intptr_t pos = offset + buffer_.GetPosition(); |