Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: runtime/vm/assembler_x64.cc

Issue 346823003: VM: Optimized context allocation on all platforms. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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::ComputeCounterAddressesForCid(intptr_t cid,
3123 Heap::Space space,
3124 Address* count_address,
3125 Address* size_address) {
3126 ASSERT(cid < kNumPredefinedCids);
3127 Register temp_reg = TMP;
3128 Isolate* isolate = Isolate::Current();
3129 ClassTable* class_table = isolate->class_table();
3130 const uword class_heap_stats_table_address =
3131 class_table->PredefinedClassHeapStatsTableAddress();
3132 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT
3133 const uword count_field_offset = (space == Heap::kNew)
3134 ? ClassHeapStats::allocated_since_gc_new_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()
3138 : ClassHeapStats::allocated_size_since_gc_old_space_offset();
3139 movq(temp_reg, Immediate(class_heap_stats_table_address + class_offset));
3140 *count_address = Address(temp_reg, count_field_offset);
3141 *size_address = Address(temp_reg, size_field_offset);
3142 }
3143
3144
3122 void Assembler::UpdateAllocationStats(intptr_t cid, 3145 void Assembler::UpdateAllocationStats(intptr_t cid,
3123 Heap::Space space) { 3146 Heap::Space space) {
3124 Register temp_reg = TMP;
3125 ASSERT(cid > 0); 3147 ASSERT(cid > 0);
3126 Isolate* isolate = Isolate::Current();
3127 ClassTable* class_table = isolate->class_table();
3128 if (cid < kNumPredefinedCids) { 3148 if (cid < kNumPredefinedCids) {
3129 const uword class_heap_stats_table_address = 3149 Address count_address(kNoRegister, 0), size_address(kNoRegister, 0);
3130 class_table->PredefinedClassHeapStatsTableAddress(); 3150 ComputeCounterAddressesForCid(cid, space, &count_address, &size_address);
3131 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT
3132 const uword count_field_offset = (space == Heap::kNew) ?
3133 ClassHeapStats::allocated_since_gc_new_space_offset() :
3134 ClassHeapStats::allocated_since_gc_old_space_offset();
3135 movq(temp_reg, Immediate(class_heap_stats_table_address + class_offset));
3136 const Address& count_address = Address(temp_reg, count_field_offset);
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698