| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/crankshaft/hydrogen-instructions.h" | 5 #include "src/crankshaft/hydrogen-instructions.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/safe_math.h" | 8 #include "src/base/safe_math.h" |
| 9 #include "src/crankshaft/hydrogen-infer-representation.h" | 9 #include "src/crankshaft/hydrogen-infer-representation.h" |
| 10 #include "src/double.h" | 10 #include "src/double.h" |
| (...skipping 3235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3246 } | 3246 } |
| 3247 | 3247 |
| 3248 dominator_allocate->UpdateSize(new_dominator_size_value); | 3248 dominator_allocate->UpdateSize(new_dominator_size_value); |
| 3249 | 3249 |
| 3250 if (MustAllocateDoubleAligned()) { | 3250 if (MustAllocateDoubleAligned()) { |
| 3251 if (!dominator_allocate->MustAllocateDoubleAligned()) { | 3251 if (!dominator_allocate->MustAllocateDoubleAligned()) { |
| 3252 dominator_allocate->MakeDoubleAligned(); | 3252 dominator_allocate->MakeDoubleAligned(); |
| 3253 } | 3253 } |
| 3254 } | 3254 } |
| 3255 | 3255 |
| 3256 bool keep_heap_iterable = FLAG_log_gc || FLAG_heap_stats; | 3256 if (!dominator_allocate->IsAllocationFoldingDominator()) { |
| 3257 #ifdef VERIFY_HEAP | 3257 HAllocate* first_alloc = HAllocate::New( |
| 3258 keep_heap_iterable = keep_heap_iterable || FLAG_verify_heap; | 3258 isolate, zone, dominator_allocate->context(), dominator_size, |
| 3259 #endif | 3259 dominator_allocate->type(), |
| 3260 | 3260 IsNewSpaceAllocation() ? NOT_TENURED : TENURED, JS_OBJECT_TYPE); |
| 3261 if (keep_heap_iterable) { | 3261 first_alloc->MakeAllocationFoldingDominated(); |
| 3262 dominator_allocate->MakePrefillWithFiller(); | 3262 first_alloc->InsertAfter(dominator_allocate); |
| 3263 } else { | 3263 dominator_allocate->ReplaceAllUsesWith(first_alloc); |
| 3264 // TODO(hpayer): This is a short-term hack to make allocation mementos | 3264 dominator_allocate->MakeAllocationFoldingDominator(); |
| 3265 // work again in new space. | 3265 if (FLAG_trace_allocation_folding) { |
| 3266 dominator_allocate->ClearNextMapWord(original_object_size); | 3266 PrintF("#%d (%s) inserted for dominator #%d (%s)\n", first_alloc->id(), |
| 3267 first_alloc->Mnemonic(), dominator_allocate->id(), |
| 3268 dominator_allocate->Mnemonic()); |
| 3269 } |
| 3267 } | 3270 } |
| 3268 | 3271 |
| 3269 dominator_allocate->UpdateClearNextMapWord(MustClearNextMapWord()); | 3272 MakeAllocationFoldingDominated(); |
| 3270 | 3273 |
| 3271 // After that replace the dominated allocate instruction. | |
| 3272 HInstruction* inner_offset = HConstant::CreateAndInsertBefore( | |
| 3273 isolate, zone, context(), dominator_size_constant, Representation::None(), | |
| 3274 this); | |
| 3275 | |
| 3276 HInstruction* dominated_allocate_instr = HInnerAllocatedObject::New( | |
| 3277 isolate, zone, context(), dominator_allocate, inner_offset, type()); | |
| 3278 dominated_allocate_instr->InsertBefore(this); | |
| 3279 DeleteAndReplaceWith(dominated_allocate_instr); | |
| 3280 if (FLAG_trace_allocation_folding) { | 3274 if (FLAG_trace_allocation_folding) { |
| 3281 PrintF("#%d (%s) folded into #%d (%s)\n", | 3275 PrintF("#%d (%s) folded into #%d (%s), new dominator size: %d\n", id(), |
| 3282 id(), Mnemonic(), dominator_allocate->id(), | 3276 Mnemonic(), dominator_allocate->id(), dominator_allocate->Mnemonic(), |
| 3283 dominator_allocate->Mnemonic()); | 3277 new_dominator_size); |
| 3284 } | 3278 } |
| 3285 return true; | 3279 return true; |
| 3286 } | 3280 } |
| 3287 | 3281 |
| 3288 | 3282 |
| 3289 void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) { | |
| 3290 DCHECK(filler_free_space_size_ != NULL); | |
| 3291 Zone* zone = block()->zone(); | |
| 3292 // We must explicitly force Smi representation here because on x64 we | |
| 3293 // would otherwise automatically choose int32, but the actual store | |
| 3294 // requires a Smi-tagged value. | |
| 3295 HConstant* new_free_space_size = HConstant::CreateAndInsertBefore( | |
| 3296 block()->isolate(), zone, context(), | |
| 3297 filler_free_space_size_->value()->GetInteger32Constant() + | |
| 3298 free_space_size, | |
| 3299 Representation::Smi(), filler_free_space_size_); | |
| 3300 filler_free_space_size_->UpdateValue(new_free_space_size); | |
| 3301 } | |
| 3302 | |
| 3303 | |
| 3304 void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { | |
| 3305 DCHECK(filler_free_space_size_ == NULL); | |
| 3306 Isolate* isolate = block()->isolate(); | |
| 3307 Zone* zone = block()->zone(); | |
| 3308 HInstruction* free_space_instr = | |
| 3309 HInnerAllocatedObject::New(isolate, zone, context(), dominating_allocate_, | |
| 3310 dominating_allocate_->size(), type()); | |
| 3311 free_space_instr->InsertBefore(this); | |
| 3312 HConstant* filler_map = HConstant::CreateAndInsertAfter( | |
| 3313 zone, Unique<Map>::CreateImmovable(isolate->factory()->free_space_map()), | |
| 3314 true, free_space_instr); | |
| 3315 HInstruction* store_map = | |
| 3316 HStoreNamedField::New(isolate, zone, context(), free_space_instr, | |
| 3317 HObjectAccess::ForMap(), filler_map); | |
| 3318 store_map->SetFlag(HValue::kHasNoObservableSideEffects); | |
| 3319 store_map->InsertAfter(filler_map); | |
| 3320 | |
| 3321 // We must explicitly force Smi representation here because on x64 we | |
| 3322 // would otherwise automatically choose int32, but the actual store | |
| 3323 // requires a Smi-tagged value. | |
| 3324 HConstant* filler_size = | |
| 3325 HConstant::CreateAndInsertAfter(isolate, zone, context(), free_space_size, | |
| 3326 Representation::Smi(), store_map); | |
| 3327 // Must force Smi representation for x64 (see comment above). | |
| 3328 HObjectAccess access = HObjectAccess::ForMapAndOffset( | |
| 3329 isolate->factory()->free_space_map(), FreeSpace::kSizeOffset, | |
| 3330 Representation::Smi()); | |
| 3331 HStoreNamedField* store_size = HStoreNamedField::New( | |
| 3332 isolate, zone, context(), free_space_instr, access, filler_size); | |
| 3333 store_size->SetFlag(HValue::kHasNoObservableSideEffects); | |
| 3334 store_size->InsertAfter(filler_size); | |
| 3335 filler_free_space_size_ = store_size; | |
| 3336 } | |
| 3337 | |
| 3338 | |
| 3339 void HAllocate::ClearNextMapWord(int offset) { | |
| 3340 if (MustClearNextMapWord()) { | |
| 3341 Zone* zone = block()->zone(); | |
| 3342 HObjectAccess access = | |
| 3343 HObjectAccess::ForObservableJSObjectOffset(offset); | |
| 3344 HStoreNamedField* clear_next_map = | |
| 3345 HStoreNamedField::New(block()->isolate(), zone, context(), this, access, | |
| 3346 block()->graph()->GetConstant0()); | |
| 3347 clear_next_map->ClearAllSideEffects(); | |
| 3348 clear_next_map->InsertAfter(this); | |
| 3349 } | |
| 3350 } | |
| 3351 | |
| 3352 | |
| 3353 std::ostream& HAllocate::PrintDataTo(std::ostream& os) const { // NOLINT | 3283 std::ostream& HAllocate::PrintDataTo(std::ostream& os) const { // NOLINT |
| 3354 os << NameOf(size()) << " ("; | 3284 os << NameOf(size()) << " ("; |
| 3355 if (IsNewSpaceAllocation()) os << "N"; | 3285 if (IsNewSpaceAllocation()) os << "N"; |
| 3356 if (IsOldSpaceAllocation()) os << "P"; | 3286 if (IsOldSpaceAllocation()) os << "P"; |
| 3357 if (MustAllocateDoubleAligned()) os << "A"; | 3287 if (MustAllocateDoubleAligned()) os << "A"; |
| 3358 if (MustPrefillWithFiller()) os << "F"; | 3288 if (MustPrefillWithFiller()) os << "F"; |
| 3359 return os << ")"; | 3289 return os << ")"; |
| 3360 } | 3290 } |
| 3361 | 3291 |
| 3362 | 3292 |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4129 case HObjectAccess::kExternalMemory: | 4059 case HObjectAccess::kExternalMemory: |
| 4130 os << "[external-memory]"; | 4060 os << "[external-memory]"; |
| 4131 break; | 4061 break; |
| 4132 } | 4062 } |
| 4133 | 4063 |
| 4134 return os << "@" << access.offset(); | 4064 return os << "@" << access.offset(); |
| 4135 } | 4065 } |
| 4136 | 4066 |
| 4137 } // namespace internal | 4067 } // namespace internal |
| 4138 } // namespace v8 | 4068 } // namespace v8 |
| OLD | NEW |