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

Side by Side Diff: src/hydrogen-instructions.cc

Issue 22378003: Added allocation folding support for old space allocations. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3288 matching lines...) Expand 10 before | Expand all | Expand 10 after
3299 // have so far but not Tagged, use that representation instead. 3299 // have so far but not Tagged, use that representation instead.
3300 Representation input_rep = value()->representation(); 3300 Representation input_rep = value()->representation();
3301 if (!input_rep.IsTagged()) rep = rep.generalize(input_rep); 3301 if (!input_rep.IsTagged()) rep = rep.generalize(input_rep);
3302 return rep; 3302 return rep;
3303 } 3303 }
3304 3304
3305 3305
3306 void HAllocate::HandleSideEffectDominator(GVNFlag side_effect, 3306 void HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
3307 HValue* dominator) { 3307 HValue* dominator) {
3308 ASSERT(side_effect == kChangesNewSpacePromotion); 3308 ASSERT(side_effect == kChangesNewSpacePromotion);
3309 Zone* zone = block()->zone();
3309 if (!FLAG_use_allocation_folding) return; 3310 if (!FLAG_use_allocation_folding) return;
3310 3311
3311 // Try to fold allocations together with their dominating allocations. 3312 // Try to fold allocations together with their dominating allocations.
3312 if (!dominator->IsAllocate()) { 3313 if (!dominator->IsAllocate()) {
3313 if (FLAG_trace_allocation_folding) { 3314 if (FLAG_trace_allocation_folding) {
3314 PrintF("#%d (%s) cannot fold into #%d (%s)\n", 3315 PrintF("#%d (%s) cannot fold into #%d (%s)\n",
3315 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); 3316 id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
3316 } 3317 }
3317 return; 3318 return;
3318 } 3319 }
3319 3320
3320 HAllocate* dominator_allocate_instr = HAllocate::cast(dominator); 3321 HAllocate* dominator_allocate = HAllocate::cast(dominator);
3321 HValue* dominator_size = dominator_allocate_instr->size(); 3322 HValue* dominator_size = dominator_allocate->size();
3322 HValue* current_size = size(); 3323 HValue* current_size = size();
3323 // We can just fold allocations that are guaranteed in new space. 3324
3324 // TODO(hpayer): Add support for non-constant allocation in dominator. 3325 // TODO(hpayer): Add support for non-constant allocation in dominator.
3325 if (!IsNewSpaceAllocation() || !current_size->IsInteger32Constant() || 3326 if (!current_size->IsInteger32Constant() ||
3326 !dominator_allocate_instr->IsNewSpaceAllocation() ||
3327 !dominator_size->IsInteger32Constant()) { 3327 !dominator_size->IsInteger32Constant()) {
3328 if (FLAG_trace_allocation_folding) { 3328 if (FLAG_trace_allocation_folding) {
3329 PrintF("#%d (%s) cannot fold into #%d (%s)\n", 3329 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic allocation size\n",
3330 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); 3330 id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
3331 } 3331 }
3332 return; 3332 return;
3333 } 3333 }
3334 3334
3335 dominator_allocate = GetFoldableDominator(dominator_allocate);
3336 if (dominator_allocate == NULL) {
3337 return;
3338 }
3339
3340 ASSERT((IsNewSpaceAllocation() &&
3341 dominator_allocate->IsNewSpaceAllocation()) ||
3342 (IsOldDataSpaceAllocation() &&
3343 dominator_allocate->IsOldDataSpaceAllocation()) ||
3344 (IsOldPointerSpaceAllocation() &&
3345 dominator_allocate->IsOldPointerSpaceAllocation()));
3346
3335 // First update the size of the dominator allocate instruction. 3347 // First update the size of the dominator allocate instruction.
3348 dominator_size = dominator_allocate->size();
3336 int32_t dominator_size_constant = 3349 int32_t dominator_size_constant =
3337 HConstant::cast(dominator_size)->GetInteger32Constant(); 3350 HConstant::cast(dominator_size)->GetInteger32Constant();
3338 int32_t current_size_constant = 3351 int32_t current_size_constant =
3339 HConstant::cast(current_size)->GetInteger32Constant(); 3352 HConstant::cast(current_size)->GetInteger32Constant();
3340 int32_t new_dominator_size = dominator_size_constant + current_size_constant; 3353 int32_t new_dominator_size = dominator_size_constant + current_size_constant;
3341 3354
3342 if (MustAllocateDoubleAligned()) { 3355 if (MustAllocateDoubleAligned()) {
3343 if (!dominator_allocate_instr->MustAllocateDoubleAligned()) { 3356 if (!dominator_allocate->MustAllocateDoubleAligned()) {
3344 dominator_allocate_instr->MakeDoubleAligned(); 3357 dominator_allocate->MakeDoubleAligned();
3345 } 3358 }
3346 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { 3359 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) {
3347 dominator_size_constant += kDoubleSize / 2; 3360 dominator_size_constant += kDoubleSize / 2;
3348 new_dominator_size += kDoubleSize / 2; 3361 new_dominator_size += kDoubleSize / 2;
3349 } 3362 }
3350 } 3363 }
3351 3364
3352 if (new_dominator_size > Page::kMaxNonCodeHeapObjectSize) { 3365 if (new_dominator_size > Page::kMaxNonCodeHeapObjectSize) {
3353 if (FLAG_trace_allocation_folding) { 3366 if (FLAG_trace_allocation_folding) {
3354 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", 3367 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n",
3355 id(), Mnemonic(), dominator->id(), dominator->Mnemonic(), 3368 id(), Mnemonic(), dominator_allocate->id(),
3356 new_dominator_size); 3369 dominator_allocate->Mnemonic(), new_dominator_size);
3357 } 3370 }
3358 return; 3371 return;
3359 } 3372 }
3360 HBasicBlock* block = dominator->block(); 3373
3361 Zone* zone = block->zone(); 3374 HInstruction* new_dominator_size_constant = HConstant::CreateAndInsert(
3362 HInstruction* new_dominator_size_constant = 3375 zone, context(), new_dominator_size, dominator_allocate, true);
3363 HConstant::New(zone, context(), new_dominator_size); 3376 dominator_allocate->UpdateSize(new_dominator_size_constant);
3364 new_dominator_size_constant->InsertBefore(dominator_allocate_instr);
3365 dominator_allocate_instr->UpdateSize(new_dominator_size_constant);
3366 3377
3367 #ifdef VERIFY_HEAP 3378 #ifdef VERIFY_HEAP
3368 if (FLAG_verify_heap) { 3379 if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) {
3369 dominator_allocate_instr->MakePrefillWithFiller(); 3380 dominator_allocate->MakePrefillWithFiller();
3370 } 3381 }
3371 #endif 3382 #endif
3372 3383
3373 // After that replace the dominated allocate instruction. 3384 // After that replace the dominated allocate instruction.
3374 HInstruction* dominated_allocate_instr = 3385 HInstruction* dominated_allocate_instr =
3375 HInnerAllocatedObject::New(zone, 3386 HInnerAllocatedObject::New(zone,
3376 context(), 3387 context(),
3377 dominator_allocate_instr, 3388 dominator_allocate,
3378 dominator_size_constant, 3389 dominator_size_constant,
3379 type()); 3390 type());
3380 dominated_allocate_instr->InsertBefore(this); 3391 dominated_allocate_instr->InsertBefore(this);
3381 DeleteAndReplaceWith(dominated_allocate_instr); 3392 DeleteAndReplaceWith(dominated_allocate_instr);
3382 if (FLAG_trace_allocation_folding) { 3393 if (FLAG_trace_allocation_folding) {
3383 PrintF("#%d (%s) folded into #%d (%s)\n", 3394 PrintF("#%d (%s) folded into #%d (%s)\n",
3384 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); 3395 id(), Mnemonic(), dominator_allocate->id(),
3396 dominator_allocate->Mnemonic());
3385 } 3397 }
3386 } 3398 }
3387 3399
3388 3400
3401 HAllocate* HAllocate::GetFoldableDominator(HAllocate* dominator) {
3402 if (!IsFoldable(dominator)) {
3403 // We cannot hoist old space allocations over new space allocations.
3404 if (IsNewSpaceAllocation() || dominator->IsNewSpaceAllocation()) {
3405 if (FLAG_trace_allocation_folding) {
3406 PrintF("#%d (%s) cannot fold into #%d (%s), new space hoisting\n",
3407 id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
3408 }
3409 return NULL;
3410 }
3411
3412 // We can hoist old data space allocations over an old pointer space
3413 // allocation and vice versa. For that we have to check the dominator
3414 // of the dominator allocate instruction.
3415 HAllocate* previous_dominator = dominator->dominating_allocate();
3416 if (previous_dominator == NULL) {
3417 set_dominating_allocate(dominator);
3418 if (FLAG_trace_allocation_folding) {
3419 PrintF("#%d (%s) cannot fold into #%d (%s), different spaces\n",
3420 id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
3421 }
3422 return NULL;
3423 }
3424
3425 // If we stored a dominator in our actual dominator, then it must be in
3426 // the space of the dominated allocation operation. We can hoist the old
3427 // space allocation over the actual dominator.
3428 dominator = previous_dominator;
3429
3430 // We can just fold old space allocations that are in the same basic block,
3431 // since it is not guaranteed that we fill up the whole allocated old
3432 // space memory.
3433 // TODO(hpayer): Remove this limitation and add filler maps for each each
3434 // allocation as soon as we have store elimination.
3435 if (block()->block_id() != dominator->block()->block_id()) {
3436 if (FLAG_trace_allocation_folding) {
3437 PrintF("#%d (%s) cannot fold into #%d (%s), different basic blocks\n",
3438 id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
3439 }
3440 return NULL;
3441 }
3442
3443 ASSERT((IsOldDataSpaceAllocation() &&
3444 dominator->IsOldDataSpaceAllocation()) ||
3445 (IsOldPointerSpaceAllocation() &&
3446 dominator->IsOldPointerSpaceAllocation()));
3447
3448 int32_t current_size = HConstant::cast(size())->GetInteger32Constant();
3449 HConstant* dominator_free_space_size = dominator->filler_free_space_size();
3450 if (dominator_free_space_size != NULL) {
3451 // We already hoisted one old space allocation, i.e., we already installed
3452 // a filler map. Hence, we just have to update the free space size.
3453 UpdateFreeSpaceFiller(dominator_free_space_size,
3454 dominator_free_space_size->GetInteger32Constant() + current_size);
3455 } else {
3456 // This is the first old space allocation that gets hoisted. We have to
3457 // install a filler map since the follwing allocation may cause a GC.
3458 int32_t dominator_size =
3459 HConstant::cast(dominator->size())->GetInteger32Constant();
3460 CreateFreeSpaceFiller(dominator, dominator_size, current_size);
3461 }
3462 }
3463 return dominator;
3464 }
3465
3466
3467 void HAllocate::UpdateFreeSpaceFiller(HConstant* old_filler_size,
3468 int32_t filler_size) {
3469 Zone* zone = block()->zone();
3470 HConstant* new_free_space_size = HConstant::CreateAndInsert(
3471 zone, context(), filler_size, old_filler_size, true);
3472 old_filler_size->DeleteAndReplaceWith(new_free_space_size);
3473 }
3474
3475
3476 void HAllocate::CreateFreeSpaceFiller(HAllocate* dominator,
3477 int32_t dominator_size,
3478 int32_t filler_size) {
3479 Zone* zone = block()->zone();
3480 HInstruction* free_space_instr =
3481 HInnerAllocatedObject::New(zone, context(), dominator, dominator_size,
3482 type());
3483 free_space_instr->InsertAfter(dominator);
3484 HConstant* filler_map = HConstant::New(
titzer 2013/08/07 11:53:44 You can use CreateAndInsert() here.
Hannes Payer (out of office) 2013/08/07 12:47:55 No, I cannot - different HConstant. Actually I am
3485 zone,
3486 context(),
3487 isolate()->factory()->free_space_map(),
3488 UniqueValueId(isolate()->heap()->free_space_map()));
3489 filler_map->InsertAfter(free_space_instr);
3490 HInstruction* store_map = HStoreNamedField::New(zone, context(),
3491 free_space_instr, HObjectAccess::ForMap(), filler_map);
3492 store_map->SetFlag(HValue::kHasNoObservableSideEffects);
3493 store_map->InsertAfter(filler_map);
3494
3495 HConstant* free_space_size = HConstant::CreateAndInsert(
3496 zone, context(), filler_size, store_map, false);
titzer 2013/08/07 11:53:44 Is there any way to make this an InsertBefore() as
Hannes Payer (out of office) 2013/08/07 12:47:55 No, it would just get to complicated. I prefer kee
3497 dominator->set_filler_free_space_size(free_space_size);
3498 HObjectAccess access =
3499 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset);
3500 HInstruction* store_size = HStoreNamedField::New(zone, context(),
3501 free_space_instr, access, free_space_size);
3502 store_size->SetFlag(HValue::kHasNoObservableSideEffects);
3503 store_size->InsertAfter(free_space_size);
3504 }
3505
3506
3389 void HAllocate::PrintDataTo(StringStream* stream) { 3507 void HAllocate::PrintDataTo(StringStream* stream) {
3390 size()->PrintNameTo(stream); 3508 size()->PrintNameTo(stream);
3391 stream->Add(" ("); 3509 stream->Add(" (");
3392 if (IsNewSpaceAllocation()) stream->Add("N"); 3510 if (IsNewSpaceAllocation()) stream->Add("N");
3393 if (IsOldPointerSpaceAllocation()) stream->Add("P"); 3511 if (IsOldPointerSpaceAllocation()) stream->Add("P");
3394 if (IsOldDataSpaceAllocation()) stream->Add("D"); 3512 if (IsOldDataSpaceAllocation()) stream->Add("D");
3395 if (MustAllocateDoubleAligned()) stream->Add("A"); 3513 if (MustAllocateDoubleAligned()) stream->Add("A");
3396 if (MustPrefillWithFiller()) stream->Add("F"); 3514 if (MustPrefillWithFiller()) stream->Add("F");
3397 stream->Add(")"); 3515 stream->Add(")");
3398 } 3516 }
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after
4120 break; 4238 break;
4121 case kExternalMemory: 4239 case kExternalMemory:
4122 stream->Add("[external-memory]"); 4240 stream->Add("[external-memory]");
4123 break; 4241 break;
4124 } 4242 }
4125 4243
4126 stream->Add("@%d", offset()); 4244 stream->Add("@%d", offset());
4127 } 4245 }
4128 4246
4129 } } // namespace v8::internal 4247 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698