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

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

Issue 23545008: Merged r16346, r16355 into trunk branch. (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 7 years, 3 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 | « src/hydrogen-instructions.h ('k') | src/version.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 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 2365 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 is_internalized_string_(is_internalize_string), 2376 is_internalized_string_(is_internalize_string),
2377 is_not_in_new_space_(is_not_in_new_space), 2377 is_not_in_new_space_(is_not_in_new_space),
2378 is_cell_(is_cell), 2378 is_cell_(is_cell),
2379 boolean_value_(boolean_value) { 2379 boolean_value_(boolean_value) {
2380 ASSERT(!handle.is_null()); 2380 ASSERT(!handle.is_null());
2381 ASSERT(!type.IsTaggedNumber()); 2381 ASSERT(!type.IsTaggedNumber());
2382 Initialize(r); 2382 Initialize(r);
2383 } 2383 }
2384 2384
2385 2385
2386 HConstant::HConstant(Handle<Map> handle,
2387 UniqueValueId unique_id)
2388 : HTemplateInstruction<0>(HType::Tagged()),
2389 handle_(handle),
2390 unique_id_(unique_id),
2391 has_smi_value_(false),
2392 has_int32_value_(false),
2393 has_double_value_(false),
2394 has_external_reference_value_(false),
2395 is_internalized_string_(false),
2396 is_not_in_new_space_(true),
2397 is_cell_(false),
2398 boolean_value_(false) {
2399 ASSERT(!handle.is_null());
2400 Initialize(Representation::Tagged());
2401 }
2402
2403
2386 HConstant::HConstant(int32_t integer_value, 2404 HConstant::HConstant(int32_t integer_value,
2387 Representation r, 2405 Representation r,
2388 bool is_not_in_new_space, 2406 bool is_not_in_new_space,
2389 Handle<Object> optional_handle) 2407 Handle<Object> optional_handle)
2390 : handle_(optional_handle), 2408 : handle_(optional_handle),
2391 unique_id_(), 2409 unique_id_(),
2392 has_smi_value_(Smi::IsValid(integer_value)), 2410 has_smi_value_(Smi::IsValid(integer_value)),
2393 has_int32_value_(true), 2411 has_int32_value_(true),
2394 has_double_value_(true), 2412 has_double_value_(true),
2395 has_external_reference_value_(false), 2413 has_external_reference_value_(false),
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
3190 if (!input_rep.IsTagged()) { 3208 if (!input_rep.IsTagged()) {
3191 rep = rep.generalize(input_rep); 3209 rep = rep.generalize(input_rep);
3192 } 3210 }
3193 return rep; 3211 return rep;
3194 } 3212 }
3195 3213
3196 3214
3197 void HAllocate::HandleSideEffectDominator(GVNFlag side_effect, 3215 void HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
3198 HValue* dominator) { 3216 HValue* dominator) {
3199 ASSERT(side_effect == kChangesNewSpacePromotion); 3217 ASSERT(side_effect == kChangesNewSpacePromotion);
3218 Zone* zone = block()->zone();
3200 if (!FLAG_use_allocation_folding) return; 3219 if (!FLAG_use_allocation_folding) return;
3201 3220
3202 // Try to fold allocations together with their dominating allocations. 3221 // Try to fold allocations together with their dominating allocations.
3203 if (!dominator->IsAllocate()) { 3222 if (!dominator->IsAllocate()) {
3204 if (FLAG_trace_allocation_folding) { 3223 if (FLAG_trace_allocation_folding) {
3205 PrintF("#%d (%s) cannot fold into #%d (%s)\n", 3224 PrintF("#%d (%s) cannot fold into #%d (%s)\n",
3206 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); 3225 id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
3207 } 3226 }
3208 return; 3227 return;
3209 } 3228 }
3210 3229
3211 HAllocate* dominator_allocate_instr = HAllocate::cast(dominator); 3230 HAllocate* dominator_allocate = HAllocate::cast(dominator);
3212 HValue* dominator_size = dominator_allocate_instr->size(); 3231 HValue* dominator_size = dominator_allocate->size();
3213 HValue* current_size = size(); 3232 HValue* current_size = size();
3214 // We can just fold allocations that are guaranteed in new space. 3233
3215 // TODO(hpayer): Add support for non-constant allocation in dominator. 3234 // TODO(hpayer): Add support for non-constant allocation in dominator.
3216 if (!IsNewSpaceAllocation() || !current_size->IsInteger32Constant() || 3235 if (!current_size->IsInteger32Constant() ||
3217 !dominator_allocate_instr->IsNewSpaceAllocation() ||
3218 !dominator_size->IsInteger32Constant()) { 3236 !dominator_size->IsInteger32Constant()) {
3219 if (FLAG_trace_allocation_folding) { 3237 if (FLAG_trace_allocation_folding) {
3220 PrintF("#%d (%s) cannot fold into #%d (%s)\n", 3238 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic allocation size\n",
3221 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); 3239 id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
3222 } 3240 }
3223 return; 3241 return;
3224 } 3242 }
3225 3243
3244 dominator_allocate = GetFoldableDominator(dominator_allocate);
3245 if (dominator_allocate == NULL) {
3246 return;
3247 }
3248
3249 ASSERT((IsNewSpaceAllocation() &&
3250 dominator_allocate->IsNewSpaceAllocation()) ||
3251 (IsOldDataSpaceAllocation() &&
3252 dominator_allocate->IsOldDataSpaceAllocation()) ||
3253 (IsOldPointerSpaceAllocation() &&
3254 dominator_allocate->IsOldPointerSpaceAllocation()));
3255
3226 // First update the size of the dominator allocate instruction. 3256 // First update the size of the dominator allocate instruction.
3257 dominator_size = dominator_allocate->size();
3227 int32_t dominator_size_constant = 3258 int32_t dominator_size_constant =
3228 HConstant::cast(dominator_size)->GetInteger32Constant(); 3259 HConstant::cast(dominator_size)->GetInteger32Constant();
3229 int32_t current_size_constant = 3260 int32_t current_size_constant =
3230 HConstant::cast(current_size)->GetInteger32Constant(); 3261 HConstant::cast(current_size)->GetInteger32Constant();
3231 int32_t new_dominator_size = dominator_size_constant + current_size_constant; 3262 int32_t new_dominator_size = dominator_size_constant + current_size_constant;
3232 3263
3233 if (MustAllocateDoubleAligned()) { 3264 if (MustAllocateDoubleAligned()) {
3234 if (!dominator_allocate_instr->MustAllocateDoubleAligned()) { 3265 if (!dominator_allocate->MustAllocateDoubleAligned()) {
3235 dominator_allocate_instr->MakeDoubleAligned(); 3266 dominator_allocate->MakeDoubleAligned();
3236 } 3267 }
3237 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { 3268 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) {
3238 dominator_size_constant += kDoubleSize / 2; 3269 dominator_size_constant += kDoubleSize / 2;
3239 new_dominator_size += kDoubleSize / 2; 3270 new_dominator_size += kDoubleSize / 2;
3240 } 3271 }
3241 } 3272 }
3242 3273
3243 if (new_dominator_size > Page::kMaxNonCodeHeapObjectSize) { 3274 if (new_dominator_size > Page::kMaxNonCodeHeapObjectSize) {
3244 if (FLAG_trace_allocation_folding) { 3275 if (FLAG_trace_allocation_folding) {
3245 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", 3276 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n",
3246 id(), Mnemonic(), dominator->id(), dominator->Mnemonic(), 3277 id(), Mnemonic(), dominator_allocate->id(),
3247 new_dominator_size); 3278 dominator_allocate->Mnemonic(), new_dominator_size);
3248 } 3279 }
3249 return; 3280 return;
3250 } 3281 }
3251 HBasicBlock* block = dominator->block(); 3282
3252 Zone* zone = block->zone(); 3283 HInstruction* new_dominator_size_constant = HConstant::CreateAndInsertBefore(
3253 HInstruction* new_dominator_size_constant = 3284 zone,
3254 HConstant::New(zone, context(), new_dominator_size); 3285 context(),
3255 new_dominator_size_constant->InsertBefore(dominator_allocate_instr); 3286 new_dominator_size,
3256 dominator_allocate_instr->UpdateSize(new_dominator_size_constant); 3287 Representation::None(),
3288 dominator_allocate);
3289 dominator_allocate->UpdateSize(new_dominator_size_constant);
3257 3290
3258 #ifdef VERIFY_HEAP 3291 #ifdef VERIFY_HEAP
3259 if (FLAG_verify_heap) { 3292 if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) {
3260 dominator_allocate_instr->MakePrefillWithFiller(); 3293 dominator_allocate->MakePrefillWithFiller();
3261 } 3294 }
3262 #endif 3295 #endif
3263 3296
3264 // After that replace the dominated allocate instruction. 3297 // After that replace the dominated allocate instruction.
3265 HInstruction* dominated_allocate_instr = 3298 HInstruction* dominated_allocate_instr =
3266 HInnerAllocatedObject::New(zone, 3299 HInnerAllocatedObject::New(zone,
3267 context(), 3300 context(),
3268 dominator_allocate_instr, 3301 dominator_allocate,
3269 dominator_size_constant, 3302 dominator_size_constant,
3270 type()); 3303 type());
3271 dominated_allocate_instr->InsertBefore(this); 3304 dominated_allocate_instr->InsertBefore(this);
3272 DeleteAndReplaceWith(dominated_allocate_instr); 3305 DeleteAndReplaceWith(dominated_allocate_instr);
3273 if (FLAG_trace_allocation_folding) { 3306 if (FLAG_trace_allocation_folding) {
3274 PrintF("#%d (%s) folded into #%d (%s)\n", 3307 PrintF("#%d (%s) folded into #%d (%s)\n",
3275 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); 3308 id(), Mnemonic(), dominator_allocate->id(),
3309 dominator_allocate->Mnemonic());
3276 } 3310 }
3277 } 3311 }
3278 3312
3279 3313
3314 HAllocate* HAllocate::GetFoldableDominator(HAllocate* dominator) {
3315 if (!IsFoldable(dominator)) {
3316 // We cannot hoist old space allocations over new space allocations.
3317 if (IsNewSpaceAllocation() || dominator->IsNewSpaceAllocation()) {
3318 if (FLAG_trace_allocation_folding) {
3319 PrintF("#%d (%s) cannot fold into #%d (%s), new space hoisting\n",
3320 id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
3321 }
3322 return NULL;
3323 }
3324
3325 HAllocate* dominator_dominator = dominator->dominating_allocate_;
3326
3327 // We can hoist old data space allocations over an old pointer space
3328 // allocation and vice versa. For that we have to check the dominator
3329 // of the dominator allocate instruction.
3330 if (dominator_dominator == NULL) {
3331 dominating_allocate_ = dominator;
3332 if (FLAG_trace_allocation_folding) {
3333 PrintF("#%d (%s) cannot fold into #%d (%s), different spaces\n",
3334 id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
3335 }
3336 return NULL;
3337 }
3338
3339 // We can just fold old space allocations that are in the same basic block,
3340 // since it is not guaranteed that we fill up the whole allocated old
3341 // space memory.
3342 // TODO(hpayer): Remove this limitation and add filler maps for each each
3343 // allocation as soon as we have store elimination.
3344 if (block()->block_id() != dominator_dominator->block()->block_id()) {
3345 if (FLAG_trace_allocation_folding) {
3346 PrintF("#%d (%s) cannot fold into #%d (%s), different basic blocks\n",
3347 id(), Mnemonic(), dominator_dominator->id(),
3348 dominator_dominator->Mnemonic());
3349 }
3350 return NULL;
3351 }
3352
3353 ASSERT((IsOldDataSpaceAllocation() &&
3354 dominator_dominator->IsOldDataSpaceAllocation()) ||
3355 (IsOldPointerSpaceAllocation() &&
3356 dominator_dominator->IsOldPointerSpaceAllocation()));
3357
3358 int32_t current_size = HConstant::cast(size())->GetInteger32Constant();
3359 HStoreNamedField* dominator_free_space_size =
3360 dominator->filler_free_space_size_;
3361 if (dominator_free_space_size != NULL) {
3362 // We already hoisted one old space allocation, i.e., we already installed
3363 // a filler map. Hence, we just have to update the free space size.
3364 dominator->UpdateFreeSpaceFiller(current_size);
3365 } else {
3366 // This is the first old space allocation that gets hoisted. We have to
3367 // install a filler map since the follwing allocation may cause a GC.
3368 dominator->CreateFreeSpaceFiller(current_size);
3369 }
3370
3371 // We can hoist the old space allocation over the actual dominator.
3372 return dominator_dominator;
3373 }
3374 return dominator;
3375 }
3376
3377
3378 void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) {
3379 ASSERT(filler_free_space_size_ != NULL);
3380 Zone* zone = block()->zone();
3381 // We must explicitly force Smi representation here because on x64 we
3382 // would otherwise automatically choose int32, but the actual store
3383 // requires a Smi-tagged value.
3384 HConstant* new_free_space_size = HConstant::CreateAndInsertBefore(
3385 zone,
3386 context(),
3387 filler_free_space_size_->value()->GetInteger32Constant() +
3388 free_space_size,
3389 Representation::Smi(),
3390 filler_free_space_size_);
3391 filler_free_space_size_->UpdateValue(new_free_space_size);
3392 }
3393
3394
3395 void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
3396 ASSERT(filler_free_space_size_ == NULL);
3397 Zone* zone = block()->zone();
3398 int32_t dominator_size =
3399 HConstant::cast(dominating_allocate_->size())->GetInteger32Constant();
3400 HInstruction* free_space_instr =
3401 HInnerAllocatedObject::New(zone, context(), dominating_allocate_,
3402 dominator_size, type());
3403 free_space_instr->InsertBefore(this);
3404 HConstant* filler_map = HConstant::New(
3405 zone,
3406 context(),
3407 isolate()->factory()->free_space_map(),
3408 UniqueValueId(isolate()->heap()->free_space_map()));
3409 filler_map->InsertAfter(free_space_instr);
3410 HInstruction* store_map = HStoreNamedField::New(zone, context(),
3411 free_space_instr, HObjectAccess::ForMap(), filler_map);
3412 store_map->SetFlag(HValue::kHasNoObservableSideEffects);
3413 store_map->InsertAfter(filler_map);
3414
3415 // We must explicitly force Smi representation here because on x64 we
3416 // would otherwise automatically choose int32, but the actual store
3417 // requires a Smi-tagged value.
3418 HConstant* filler_size = HConstant::CreateAndInsertAfter(
3419 zone, context(), free_space_size, Representation::Smi(), store_map);
3420 // Must force Smi representation for x64 (see comment above).
3421 HObjectAccess access =
3422 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset,
3423 Representation::Smi());
3424 HStoreNamedField* store_size = HStoreNamedField::New(zone, context(),
3425 free_space_instr, access, filler_size);
3426 store_size->SetFlag(HValue::kHasNoObservableSideEffects);
3427 store_size->InsertAfter(filler_size);
3428 filler_free_space_size_ = store_size;
3429 }
3430
3431
3280 void HAllocate::PrintDataTo(StringStream* stream) { 3432 void HAllocate::PrintDataTo(StringStream* stream) {
3281 size()->PrintNameTo(stream); 3433 size()->PrintNameTo(stream);
3282 stream->Add(" ("); 3434 stream->Add(" (");
3283 if (IsNewSpaceAllocation()) stream->Add("N"); 3435 if (IsNewSpaceAllocation()) stream->Add("N");
3284 if (IsOldPointerSpaceAllocation()) stream->Add("P"); 3436 if (IsOldPointerSpaceAllocation()) stream->Add("P");
3285 if (IsOldDataSpaceAllocation()) stream->Add("D"); 3437 if (IsOldDataSpaceAllocation()) stream->Add("D");
3286 if (MustAllocateDoubleAligned()) stream->Add("A"); 3438 if (MustAllocateDoubleAligned()) stream->Add("A");
3287 if (MustPrefillWithFiller()) stream->Add("F"); 3439 if (MustPrefillWithFiller()) stream->Add("F");
3288 stream->Add(")"); 3440 stream->Add(")");
3289 } 3441 }
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after
4011 break; 4163 break;
4012 case kExternalMemory: 4164 case kExternalMemory:
4013 stream->Add("[external-memory]"); 4165 stream->Add("[external-memory]");
4014 break; 4166 break;
4015 } 4167 }
4016 4168
4017 stream->Add("@%d", offset()); 4169 stream->Add("@%d", offset());
4018 } 4170 }
4019 4171
4020 } } // namespace v8::internal 4172 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/version.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698