Chromium Code Reviews| 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_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/heap.h" | 10 #include "vm/heap.h" |
| (...skipping 3101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3112 } | 3112 } |
| 3113 | 3113 |
| 3114 | 3114 |
| 3115 void Assembler::LeaveStubFrame() { | 3115 void Assembler::LeaveStubFrame() { |
| 3116 // Restore caller's PP register that was pushed in EnterStubFrame. | 3116 // Restore caller's PP register that was pushed in EnterStubFrame. |
| 3117 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); | 3117 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); |
| 3118 LeaveFrame(); | 3118 LeaveFrame(); |
| 3119 } | 3119 } |
| 3120 | 3120 |
| 3121 | 3121 |
| 3122 void Assembler::UpdateAllocationStats(intptr_t cid, | 3122 void Assembler::ComputeCounterAddressesForCid(intptr_t cid, |
| 3123 Heap::Space space) { | 3123 Heap::Space space, |
| 3124 Address* count_address, | |
| 3125 Address* size_address) { | |
| 3126 ASSERT(cid < kNumPredefinedCids); | |
| 3124 Register temp_reg = TMP; | 3127 Register temp_reg = TMP; |
| 3125 ASSERT(cid > 0); | |
| 3126 Isolate* isolate = Isolate::Current(); | 3128 Isolate* isolate = Isolate::Current(); |
| 3127 ClassTable* class_table = isolate->class_table(); | 3129 ClassTable* class_table = isolate->class_table(); |
| 3128 if (cid < kNumPredefinedCids) { | |
| 3129 const uword class_heap_stats_table_address = | 3130 const uword class_heap_stats_table_address = |
| 3130 class_table->PredefinedClassHeapStatsTableAddress(); | 3131 class_table->PredefinedClassHeapStatsTableAddress(); |
| 3131 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | 3132 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| 3132 const uword count_field_offset = (space == Heap::kNew) ? | 3133 const uword count_field_offset = (space == Heap::kNew) ? |
| 3133 ClassHeapStats::allocated_since_gc_new_space_offset() : | 3134 ClassHeapStats::allocated_since_gc_new_space_offset() : |
| 3134 ClassHeapStats::allocated_since_gc_old_space_offset(); | 3135 ClassHeapStats::allocated_since_gc_old_space_offset(); |
| 3136 const uword size_field_offset = (space == Heap::kNew) ? | |
| 3137 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.
| |
| 3138 ClassHeapStats::allocated_size_since_gc_old_space_offset(); | |
| 3135 movq(temp_reg, Immediate(class_heap_stats_table_address + class_offset)); | 3139 movq(temp_reg, Immediate(class_heap_stats_table_address + class_offset)); |
| 3136 const Address& count_address = Address(temp_reg, count_field_offset); | 3140 *count_address = Address(temp_reg, count_field_offset); |
| 3141 *size_address = Address(temp_reg, size_field_offset); | |
| 3142 } | |
| 3143 | |
| 3144 | |
| 3145 void Assembler::UpdateAllocationStats(intptr_t cid, | |
| 3146 Heap::Space space) { | |
| 3147 ASSERT(cid > 0); | |
| 3148 if (cid < kNumPredefinedCids) { | |
| 3149 Address count_address(kNoRegister, 0), size_address(kNoRegister, 0); | |
| 3150 ComputeCounterAddressesForCid(cid, space, &count_address, &size_address); | |
| 3137 incq(count_address); | 3151 incq(count_address); |
| 3138 } else { | 3152 } else { |
| 3139 ASSERT(temp_reg != kNoRegister); | 3153 Register temp_reg = TMP; |
| 3140 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | 3154 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| 3141 const uword count_field_offset = (space == Heap::kNew) ? | 3155 const uword count_field_offset = (space == Heap::kNew) ? |
| 3142 ClassHeapStats::allocated_since_gc_new_space_offset() : | 3156 ClassHeapStats::allocated_since_gc_new_space_offset() : |
| 3143 ClassHeapStats::allocated_since_gc_old_space_offset(); | 3157 ClassHeapStats::allocated_since_gc_old_space_offset(); |
| 3158 ClassTable* class_table = Isolate::Current()->class_table(); | |
| 3144 movq(temp_reg, Immediate(class_table->ClassStatsTableAddress())); | 3159 movq(temp_reg, Immediate(class_table->ClassStatsTableAddress())); |
| 3145 movq(temp_reg, Address(temp_reg, 0)); | 3160 movq(temp_reg, Address(temp_reg, 0)); |
| 3146 incq(Address(temp_reg, class_offset + count_field_offset)); | 3161 incq(Address(temp_reg, class_offset + count_field_offset)); |
| 3147 } | 3162 } |
| 3148 } | 3163 } |
| 3149 | 3164 |
| 3150 | 3165 |
| 3151 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, | 3166 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, |
| 3152 Register size_reg, | 3167 Register size_reg, |
| 3153 Heap::Space space) { | 3168 Heap::Space space) { |
| 3154 Register temp_reg = TMP; | |
| 3155 ASSERT(cid > 0); | 3169 ASSERT(cid > 0); |
| 3156 Isolate* isolate = Isolate::Current(); | 3170 ASSERT(cid < kNumPredefinedCids); |
| 3157 ClassTable* class_table = isolate->class_table(); | 3171 Address count_address(kNoRegister, 0), size_address(kNoRegister, 0); |
| 3158 if (cid < kNumPredefinedCids) { | 3172 ComputeCounterAddressesForCid(cid, space, &count_address, &size_address); |
| 3159 const uword class_heap_stats_table_address = | 3173 incq(count_address); |
| 3160 class_table->PredefinedClassHeapStatsTableAddress(); | 3174 addq(size_address, size_reg); |
| 3161 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | 3175 } |
| 3162 const uword count_field_offset = (space == Heap::kNew) ? | 3176 |
| 3163 ClassHeapStats::allocated_since_gc_new_space_offset() : | 3177 |
| 3164 ClassHeapStats::allocated_since_gc_old_space_offset(); | 3178 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, |
| 3165 const uword size_field_offset = (space == Heap::kNew) ? | 3179 intptr_t size_in_bytes, |
| 3166 ClassHeapStats::allocated_size_since_gc_new_space_offset() : | 3180 Heap::Space space) { |
| 3167 ClassHeapStats::allocated_size_since_gc_old_space_offset(); | 3181 ASSERT(cid > 0); |
| 3168 movq(temp_reg, Immediate(class_heap_stats_table_address + class_offset)); | 3182 ASSERT(cid < kNumPredefinedCids); |
| 3169 const Address& count_address = Address(temp_reg, count_field_offset); | 3183 Address count_address(kNoRegister, 0), size_address(kNoRegister, 0); |
| 3170 const Address& size_address = Address(temp_reg, size_field_offset); | 3184 ComputeCounterAddressesForCid(cid, space, &count_address, &size_address); |
| 3171 incq(count_address); | 3185 incq(count_address); |
| 3172 addq(size_address, size_reg); | 3186 addq(size_address, Immediate(size_in_bytes)); |
| 3173 } else { | |
| 3174 ASSERT(temp_reg != kNoRegister); | |
| 3175 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | |
| 3176 const uword count_field_offset = (space == Heap::kNew) ? | |
| 3177 ClassHeapStats::allocated_since_gc_new_space_offset() : | |
| 3178 ClassHeapStats::allocated_since_gc_old_space_offset(); | |
| 3179 const uword size_field_offset = (space == Heap::kNew) ? | |
| 3180 ClassHeapStats::allocated_size_since_gc_new_space_offset() : | |
| 3181 ClassHeapStats::allocated_size_since_gc_old_space_offset(); | |
| 3182 movq(temp_reg, Immediate(class_table->ClassStatsTableAddress())); | |
| 3183 movq(temp_reg, Address(temp_reg, 0)); | |
| 3184 incq(Address(temp_reg, class_offset + count_field_offset)); | |
| 3185 addq(Address(temp_reg, class_offset + size_field_offset), size_reg); | |
| 3186 } | |
| 3187 } | 3187 } |
| 3188 | 3188 |
| 3189 | 3189 |
| 3190 void Assembler::TryAllocate(const Class& cls, | 3190 void Assembler::TryAllocate(const Class& cls, |
| 3191 Label* failure, | 3191 Label* failure, |
| 3192 bool near_jump, | 3192 bool near_jump, |
| 3193 Register instance_reg, | 3193 Register instance_reg, |
| 3194 Register pp) { | 3194 Register pp) { |
| 3195 ASSERT(failure != NULL); | 3195 ASSERT(failure != NULL); |
| 3196 if (FLAG_inline_alloc) { | 3196 if (FLAG_inline_alloc) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 3215 ASSERT(cls.id() != kIllegalCid); | 3215 ASSERT(cls.id() != kIllegalCid); |
| 3216 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 3216 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 3217 LoadImmediate(FieldAddress(instance_reg, Object::tags_offset()), | 3217 LoadImmediate(FieldAddress(instance_reg, Object::tags_offset()), |
| 3218 Immediate(tags), pp); | 3218 Immediate(tags), pp); |
| 3219 } else { | 3219 } else { |
| 3220 jmp(failure); | 3220 jmp(failure); |
| 3221 } | 3221 } |
| 3222 } | 3222 } |
| 3223 | 3223 |
| 3224 | 3224 |
| 3225 void Assembler::TryAllocateArray(intptr_t cid, | |
| 3226 intptr_t instance_size, | |
| 3227 Label* failure, | |
| 3228 bool near_jump, | |
| 3229 Register instance, | |
| 3230 Register end_address) { | |
| 3231 ASSERT(failure != NULL); | |
| 3232 if (FLAG_inline_alloc) { | |
| 3233 Isolate* isolate = Isolate::Current(); | |
| 3234 Heap* heap = isolate->heap(); | |
| 3235 | |
| 3236 movq(instance, Immediate(heap->TopAddress())); | |
| 3237 movq(instance, Address(instance, 0)); | |
| 3238 movq(end_address, RAX); | |
| 3239 | |
| 3240 addq(end_address, Immediate(instance_size)); | |
| 3241 j(CARRY, failure); | |
| 3242 | |
| 3243 // Check if the allocation fits into the remaining space. | |
| 3244 // instance: potential new object start. | |
| 3245 // end_address: potential next object start. | |
| 3246 movq(TMP, Immediate(heap->EndAddress())); | |
| 3247 cmpq(end_address, Address(TMP, 0)); | |
| 3248 j(ABOVE_EQUAL, failure); | |
| 3249 | |
| 3250 // Successfully allocated the object(s), now update top to point to | |
| 3251 // next object start and initialize the object. | |
| 3252 movq(TMP, Immediate(heap->TopAddress())); | |
| 3253 movq(Address(TMP, 0), end_address); | |
| 3254 addq(instance, Immediate(kHeapObjectTag)); | |
| 3255 UpdateAllocationStatsWithSize(kArrayCid, instance_size); | |
| 3256 | |
| 3257 // Initialize the tags. | |
| 3258 // instance: new object start as a tagged pointer. | |
| 3259 uword tags = 0; | |
| 3260 tags = RawObject::ClassIdTag::update(cid, tags); | |
| 3261 tags = RawObject::SizeTag::update(instance_size, tags); | |
| 3262 movq(FieldAddress(instance, Array::tags_offset()), Immediate(tags)); | |
| 3263 } else { | |
| 3264 jmp(failure); | |
| 3265 } | |
| 3266 } | |
| 3267 | |
| 3225 void Assembler::Align(int alignment, intptr_t offset) { | 3268 void Assembler::Align(int alignment, intptr_t offset) { |
| 3226 ASSERT(Utils::IsPowerOfTwo(alignment)); | 3269 ASSERT(Utils::IsPowerOfTwo(alignment)); |
| 3227 intptr_t pos = offset + buffer_.GetPosition(); | 3270 intptr_t pos = offset + buffer_.GetPosition(); |
| 3228 int mod = pos & (alignment - 1); | 3271 int mod = pos & (alignment - 1); |
| 3229 if (mod == 0) { | 3272 if (mod == 0) { |
| 3230 return; | 3273 return; |
| 3231 } | 3274 } |
| 3232 intptr_t bytes_needed = alignment - mod; | 3275 intptr_t bytes_needed = alignment - mod; |
| 3233 while (bytes_needed > MAX_NOP_SIZE) { | 3276 while (bytes_needed > MAX_NOP_SIZE) { |
| 3234 nop(MAX_NOP_SIZE); | 3277 nop(MAX_NOP_SIZE); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3480 | 3523 |
| 3481 | 3524 |
| 3482 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3525 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3483 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3526 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 3484 return xmm_reg_names[reg]; | 3527 return xmm_reg_names[reg]; |
| 3485 } | 3528 } |
| 3486 | 3529 |
| 3487 } // namespace dart | 3530 } // namespace dart |
| 3488 | 3531 |
| 3489 #endif // defined TARGET_ARCH_X64 | 3532 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |