| OLD | NEW |
| 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 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1112 } | 1112 } |
| 1113 *block = NULL; | 1113 *block = NULL; |
| 1114 return false; | 1114 return false; |
| 1115 } | 1115 } |
| 1116 | 1116 |
| 1117 | 1117 |
| 1118 void HCompareMap::PrintDataTo(StringStream* stream) { | 1118 void HCompareMap::PrintDataTo(StringStream* stream) { |
| 1119 value()->PrintNameTo(stream); | 1119 value()->PrintNameTo(stream); |
| 1120 stream->Add(" (%p)", *map().handle()); | 1120 stream->Add(" (%p)", *map().handle()); |
| 1121 HControlInstruction::PrintDataTo(stream); | 1121 HControlInstruction::PrintDataTo(stream); |
| 1122 if (known_successor_index() == 0) { |
| 1123 stream->Add(" [true]"); |
| 1124 } else if (known_successor_index() == 1) { |
| 1125 stream->Add(" [false]"); |
| 1126 } |
| 1122 } | 1127 } |
| 1123 | 1128 |
| 1124 | 1129 |
| 1125 const char* HUnaryMathOperation::OpName() const { | 1130 const char* HUnaryMathOperation::OpName() const { |
| 1126 switch (op()) { | 1131 switch (op()) { |
| 1127 case kMathFloor: return "floor"; | 1132 case kMathFloor: return "floor"; |
| 1128 case kMathRound: return "round"; | 1133 case kMathRound: return "round"; |
| 1129 case kMathAbs: return "abs"; | 1134 case kMathAbs: return "abs"; |
| 1130 case kMathLog: return "log"; | 1135 case kMathLog: return "log"; |
| 1131 case kMathExp: return "exp"; | 1136 case kMathExp: return "exp"; |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 case IS_INTERNALIZED_STRING: | 1509 case IS_INTERNALIZED_STRING: |
| 1505 *mask = kIsNotStringMask | kIsNotInternalizedMask; | 1510 *mask = kIsNotStringMask | kIsNotInternalizedMask; |
| 1506 *tag = kInternalizedTag; | 1511 *tag = kInternalizedTag; |
| 1507 return; | 1512 return; |
| 1508 default: | 1513 default: |
| 1509 UNREACHABLE(); | 1514 UNREACHABLE(); |
| 1510 } | 1515 } |
| 1511 } | 1516 } |
| 1512 | 1517 |
| 1513 | 1518 |
| 1514 void HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect, | 1519 bool HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect, |
| 1515 HValue* dominator) { | 1520 HValue* dominator) { |
| 1516 ASSERT(side_effect == kChangesMaps); | 1521 ASSERT(side_effect == kChangesMaps); |
| 1517 // TODO(mstarzinger): For now we specialize on HStoreNamedField, but once | 1522 // TODO(mstarzinger): For now we specialize on HStoreNamedField, but once |
| 1518 // type information is rich enough we should generalize this to any HType | 1523 // type information is rich enough we should generalize this to any HType |
| 1519 // for which the map is known. | 1524 // for which the map is known. |
| 1520 if (HasNoUses() && dominator->IsStoreNamedField()) { | 1525 if (HasNoUses() && dominator->IsStoreNamedField()) { |
| 1521 HStoreNamedField* store = HStoreNamedField::cast(dominator); | 1526 HStoreNamedField* store = HStoreNamedField::cast(dominator); |
| 1522 if (!store->has_transition() || store->object() != value()) return; | 1527 if (!store->has_transition() || store->object() != value()) return false; |
| 1523 HConstant* transition = HConstant::cast(store->transition()); | 1528 HConstant* transition = HConstant::cast(store->transition()); |
| 1524 if (map_set_.Contains(transition->GetUnique())) { | 1529 if (map_set_.Contains(transition->GetUnique())) { |
| 1525 DeleteAndReplaceWith(NULL); | 1530 DeleteAndReplaceWith(NULL); |
| 1526 return; | 1531 return true; |
| 1527 } | 1532 } |
| 1528 } | 1533 } |
| 1534 return false; |
| 1529 } | 1535 } |
| 1530 | 1536 |
| 1531 | 1537 |
| 1532 void HCheckMaps::PrintDataTo(StringStream* stream) { | 1538 void HCheckMaps::PrintDataTo(StringStream* stream) { |
| 1533 value()->PrintNameTo(stream); | 1539 value()->PrintNameTo(stream); |
| 1534 stream->Add(" [%p", *map_set_.at(0).handle()); | 1540 stream->Add(" [%p", *map_set_.at(0).handle()); |
| 1535 for (int i = 1; i < map_set_.size(); ++i) { | 1541 for (int i = 1; i < map_set_.size(); ++i) { |
| 1536 stream->Add(",%p", *map_set_.at(i).handle()); | 1542 stream->Add(",%p", *map_set_.at(i).handle()); |
| 1537 } | 1543 } |
| 1538 stream->Add("]%s", CanOmitMapChecks() ? "(omitted)" : ""); | 1544 stream->Add("]%s", CanOmitMapChecks() ? "(omitted)" : ""); |
| (...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3399 // If any of the actual input representation is more general than what we | 3405 // If any of the actual input representation is more general than what we |
| 3400 // have so far but not Tagged, use that representation instead. | 3406 // have so far but not Tagged, use that representation instead. |
| 3401 Representation input_rep = value()->representation(); | 3407 Representation input_rep = value()->representation(); |
| 3402 if (!input_rep.IsTagged()) { | 3408 if (!input_rep.IsTagged()) { |
| 3403 rep = rep.generalize(input_rep); | 3409 rep = rep.generalize(input_rep); |
| 3404 } | 3410 } |
| 3405 return rep; | 3411 return rep; |
| 3406 } | 3412 } |
| 3407 | 3413 |
| 3408 | 3414 |
| 3409 void HAllocate::HandleSideEffectDominator(GVNFlag side_effect, | 3415 bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
| 3410 HValue* dominator) { | 3416 HValue* dominator) { |
| 3411 ASSERT(side_effect == kChangesNewSpacePromotion); | 3417 ASSERT(side_effect == kChangesNewSpacePromotion); |
| 3412 Zone* zone = block()->zone(); | 3418 Zone* zone = block()->zone(); |
| 3413 if (!FLAG_use_allocation_folding) return; | 3419 if (!FLAG_use_allocation_folding) return false; |
| 3414 | 3420 |
| 3415 // Try to fold allocations together with their dominating allocations. | 3421 // Try to fold allocations together with their dominating allocations. |
| 3416 if (!dominator->IsAllocate()) { | 3422 if (!dominator->IsAllocate()) { |
| 3417 if (FLAG_trace_allocation_folding) { | 3423 if (FLAG_trace_allocation_folding) { |
| 3418 PrintF("#%d (%s) cannot fold into #%d (%s)\n", | 3424 PrintF("#%d (%s) cannot fold into #%d (%s)\n", |
| 3419 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3425 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3420 } | 3426 } |
| 3421 return; | 3427 return false; |
| 3422 } | 3428 } |
| 3423 | 3429 |
| 3424 HAllocate* dominator_allocate = HAllocate::cast(dominator); | 3430 HAllocate* dominator_allocate = HAllocate::cast(dominator); |
| 3425 HValue* dominator_size = dominator_allocate->size(); | 3431 HValue* dominator_size = dominator_allocate->size(); |
| 3426 HValue* current_size = size(); | 3432 HValue* current_size = size(); |
| 3427 | 3433 |
| 3428 // TODO(hpayer): Add support for non-constant allocation in dominator. | 3434 // TODO(hpayer): Add support for non-constant allocation in dominator. |
| 3429 if (!current_size->IsInteger32Constant() || | 3435 if (!current_size->IsInteger32Constant() || |
| 3430 !dominator_size->IsInteger32Constant()) { | 3436 !dominator_size->IsInteger32Constant()) { |
| 3431 if (FLAG_trace_allocation_folding) { | 3437 if (FLAG_trace_allocation_folding) { |
| 3432 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic allocation size\n", | 3438 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic allocation size\n", |
| 3433 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3439 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3434 } | 3440 } |
| 3435 return; | 3441 return false; |
| 3436 } | 3442 } |
| 3437 | 3443 |
| 3438 dominator_allocate = GetFoldableDominator(dominator_allocate); | 3444 dominator_allocate = GetFoldableDominator(dominator_allocate); |
| 3439 if (dominator_allocate == NULL) { | 3445 if (dominator_allocate == NULL) { |
| 3440 return; | 3446 return false; |
| 3441 } | 3447 } |
| 3442 | 3448 |
| 3443 ASSERT((IsNewSpaceAllocation() && | 3449 ASSERT((IsNewSpaceAllocation() && |
| 3444 dominator_allocate->IsNewSpaceAllocation()) || | 3450 dominator_allocate->IsNewSpaceAllocation()) || |
| 3445 (IsOldDataSpaceAllocation() && | 3451 (IsOldDataSpaceAllocation() && |
| 3446 dominator_allocate->IsOldDataSpaceAllocation()) || | 3452 dominator_allocate->IsOldDataSpaceAllocation()) || |
| 3447 (IsOldPointerSpaceAllocation() && | 3453 (IsOldPointerSpaceAllocation() && |
| 3448 dominator_allocate->IsOldPointerSpaceAllocation())); | 3454 dominator_allocate->IsOldPointerSpaceAllocation())); |
| 3449 | 3455 |
| 3450 // First update the size of the dominator allocate instruction. | 3456 // First update the size of the dominator allocate instruction. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3467 } | 3473 } |
| 3468 | 3474 |
| 3469 // Since we clear the first word after folded memory, we cannot use the | 3475 // Since we clear the first word after folded memory, we cannot use the |
| 3470 // whole Page::kMaxRegularHeapObjectSize memory. | 3476 // whole Page::kMaxRegularHeapObjectSize memory. |
| 3471 if (new_dominator_size > Page::kMaxRegularHeapObjectSize - kPointerSize) { | 3477 if (new_dominator_size > Page::kMaxRegularHeapObjectSize - kPointerSize) { |
| 3472 if (FLAG_trace_allocation_folding) { | 3478 if (FLAG_trace_allocation_folding) { |
| 3473 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", | 3479 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", |
| 3474 id(), Mnemonic(), dominator_allocate->id(), | 3480 id(), Mnemonic(), dominator_allocate->id(), |
| 3475 dominator_allocate->Mnemonic(), new_dominator_size); | 3481 dominator_allocate->Mnemonic(), new_dominator_size); |
| 3476 } | 3482 } |
| 3477 return; | 3483 return false; |
| 3478 } | 3484 } |
| 3479 | 3485 |
| 3480 HInstruction* new_dominator_size_constant = HConstant::CreateAndInsertBefore( | 3486 HInstruction* new_dominator_size_constant = HConstant::CreateAndInsertBefore( |
| 3481 zone, | 3487 zone, |
| 3482 context(), | 3488 context(), |
| 3483 new_dominator_size, | 3489 new_dominator_size, |
| 3484 Representation::None(), | 3490 Representation::None(), |
| 3485 dominator_allocate); | 3491 dominator_allocate); |
| 3486 dominator_allocate->UpdateSize(new_dominator_size_constant); | 3492 dominator_allocate->UpdateSize(new_dominator_size_constant); |
| 3487 | 3493 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3515 dominator_allocate, | 3521 dominator_allocate, |
| 3516 inner_offset, | 3522 inner_offset, |
| 3517 type()); | 3523 type()); |
| 3518 dominated_allocate_instr->InsertBefore(this); | 3524 dominated_allocate_instr->InsertBefore(this); |
| 3519 DeleteAndReplaceWith(dominated_allocate_instr); | 3525 DeleteAndReplaceWith(dominated_allocate_instr); |
| 3520 if (FLAG_trace_allocation_folding) { | 3526 if (FLAG_trace_allocation_folding) { |
| 3521 PrintF("#%d (%s) folded into #%d (%s)\n", | 3527 PrintF("#%d (%s) folded into #%d (%s)\n", |
| 3522 id(), Mnemonic(), dominator_allocate->id(), | 3528 id(), Mnemonic(), dominator_allocate->id(), |
| 3523 dominator_allocate->Mnemonic()); | 3529 dominator_allocate->Mnemonic()); |
| 3524 } | 3530 } |
| 3531 return true; |
| 3525 } | 3532 } |
| 3526 | 3533 |
| 3527 | 3534 |
| 3528 HAllocate* HAllocate::GetFoldableDominator(HAllocate* dominator) { | 3535 HAllocate* HAllocate::GetFoldableDominator(HAllocate* dominator) { |
| 3529 if (!IsFoldable(dominator)) { | 3536 if (!IsFoldable(dominator)) { |
| 3530 // We cannot hoist old space allocations over new space allocations. | 3537 // We cannot hoist old space allocations over new space allocations. |
| 3531 if (IsNewSpaceAllocation() || dominator->IsNewSpaceAllocation()) { | 3538 if (IsNewSpaceAllocation() || dominator->IsNewSpaceAllocation()) { |
| 3532 if (FLAG_trace_allocation_folding) { | 3539 if (FLAG_trace_allocation_folding) { |
| 3533 PrintF("#%d (%s) cannot fold into #%d (%s), new space hoisting\n", | 3540 PrintF("#%d (%s) cannot fold into #%d (%s), new space hoisting\n", |
| 3534 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3541 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3613 HInnerAllocatedObject::New(zone, context(), dominating_allocate_, | 3620 HInnerAllocatedObject::New(zone, context(), dominating_allocate_, |
| 3614 dominating_allocate_->size(), type()); | 3621 dominating_allocate_->size(), type()); |
| 3615 free_space_instr->InsertBefore(this); | 3622 free_space_instr->InsertBefore(this); |
| 3616 HConstant* filler_map = HConstant::New( | 3623 HConstant* filler_map = HConstant::New( |
| 3617 zone, | 3624 zone, |
| 3618 context(), | 3625 context(), |
| 3619 isolate()->factory()->free_space_map()); | 3626 isolate()->factory()->free_space_map()); |
| 3620 filler_map->FinalizeUniqueness(); // TODO(titzer): should be init'd a'ready | 3627 filler_map->FinalizeUniqueness(); // TODO(titzer): should be init'd a'ready |
| 3621 filler_map->InsertAfter(free_space_instr); | 3628 filler_map->InsertAfter(free_space_instr); |
| 3622 HInstruction* store_map = HStoreNamedField::New(zone, context(), | 3629 HInstruction* store_map = HStoreNamedField::New(zone, context(), |
| 3623 free_space_instr, HObjectAccess::ForMap(), filler_map, | 3630 free_space_instr, HObjectAccess::ForMap(), filler_map); |
| 3624 INITIALIZING_STORE); | |
| 3625 store_map->SetFlag(HValue::kHasNoObservableSideEffects); | 3631 store_map->SetFlag(HValue::kHasNoObservableSideEffects); |
| 3626 store_map->InsertAfter(filler_map); | 3632 store_map->InsertAfter(filler_map); |
| 3627 | 3633 |
| 3628 // We must explicitly force Smi representation here because on x64 we | 3634 // We must explicitly force Smi representation here because on x64 we |
| 3629 // would otherwise automatically choose int32, but the actual store | 3635 // would otherwise automatically choose int32, but the actual store |
| 3630 // requires a Smi-tagged value. | 3636 // requires a Smi-tagged value. |
| 3631 HConstant* filler_size = HConstant::CreateAndInsertAfter( | 3637 HConstant* filler_size = HConstant::CreateAndInsertAfter( |
| 3632 zone, context(), free_space_size, Representation::Smi(), store_map); | 3638 zone, context(), free_space_size, Representation::Smi(), store_map); |
| 3633 // Must force Smi representation for x64 (see comment above). | 3639 // Must force Smi representation for x64 (see comment above). |
| 3634 HObjectAccess access = | 3640 HObjectAccess access = |
| 3635 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset, | 3641 HObjectAccess::ForMapAndOffset(isolate()->factory()->free_space_map(), |
| 3636 Representation::Smi()); | 3642 FreeSpace::kSizeOffset, |
| 3643 Representation::Smi()); |
| 3637 HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), | 3644 HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), |
| 3638 free_space_instr, access, filler_size, INITIALIZING_STORE); | 3645 free_space_instr, access, filler_size); |
| 3639 store_size->SetFlag(HValue::kHasNoObservableSideEffects); | 3646 store_size->SetFlag(HValue::kHasNoObservableSideEffects); |
| 3640 store_size->InsertAfter(filler_size); | 3647 store_size->InsertAfter(filler_size); |
| 3641 filler_free_space_size_ = store_size; | 3648 filler_free_space_size_ = store_size; |
| 3642 } | 3649 } |
| 3643 | 3650 |
| 3644 | 3651 |
| 3645 void HAllocate::ClearNextMapWord(int offset) { | 3652 void HAllocate::ClearNextMapWord(int offset) { |
| 3646 if (MustClearNextMapWord()) { | 3653 if (MustClearNextMapWord()) { |
| 3647 Zone* zone = block()->zone(); | 3654 Zone* zone = block()->zone(); |
| 3648 HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset); | 3655 HObjectAccess access = |
| 3656 HObjectAccess::ForObservableJSObjectOffset(offset); |
| 3649 HStoreNamedField* clear_next_map = | 3657 HStoreNamedField* clear_next_map = |
| 3650 HStoreNamedField::New(zone, context(), this, access, | 3658 HStoreNamedField::New(zone, context(), this, access, |
| 3651 block()->graph()->GetConstant0(), INITIALIZING_STORE); | 3659 block()->graph()->GetConstant0()); |
| 3652 clear_next_map->ClearAllSideEffects(); | 3660 clear_next_map->ClearAllSideEffects(); |
| 3653 clear_next_map->InsertAfter(this); | 3661 clear_next_map->InsertAfter(this); |
| 3654 } | 3662 } |
| 3655 } | 3663 } |
| 3656 | 3664 |
| 3657 | 3665 |
| 3658 void HAllocate::PrintDataTo(StringStream* stream) { | 3666 void HAllocate::PrintDataTo(StringStream* stream) { |
| 3659 size()->PrintNameTo(stream); | 3667 size()->PrintNameTo(stream); |
| 3660 stream->Add(" ("); | 3668 stream->Add(" ("); |
| 3661 if (IsNewSpaceAllocation()) stream->Add("N"); | 3669 if (IsNewSpaceAllocation()) stream->Add("N"); |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4265 | 4273 |
| 4266 | 4274 |
| 4267 HObjectAccess HObjectAccess::ForFixedArrayHeader(int offset) { | 4275 HObjectAccess HObjectAccess::ForFixedArrayHeader(int offset) { |
| 4268 ASSERT(offset >= 0); | 4276 ASSERT(offset >= 0); |
| 4269 ASSERT(offset < FixedArray::kHeaderSize); | 4277 ASSERT(offset < FixedArray::kHeaderSize); |
| 4270 if (offset == FixedArray::kLengthOffset) return ForFixedArrayLength(); | 4278 if (offset == FixedArray::kLengthOffset) return ForFixedArrayLength(); |
| 4271 return HObjectAccess(kInobject, offset); | 4279 return HObjectAccess(kInobject, offset); |
| 4272 } | 4280 } |
| 4273 | 4281 |
| 4274 | 4282 |
| 4275 HObjectAccess HObjectAccess::ForJSObjectOffset(int offset, | 4283 HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset, |
| 4276 Representation representation) { | 4284 Representation representation) { |
| 4277 ASSERT(offset >= 0); | 4285 ASSERT(offset >= 0); |
| 4278 Portion portion = kInobject; | 4286 Portion portion = kInobject; |
| 4279 | 4287 |
| 4280 if (offset == JSObject::kElementsOffset) { | 4288 if (offset == JSObject::kElementsOffset) { |
| 4281 portion = kElementsPointer; | 4289 portion = kElementsPointer; |
| 4282 } else if (offset == JSObject::kMapOffset) { | 4290 } else if (offset == JSObject::kMapOffset) { |
| 4283 portion = kMaps; | 4291 portion = kMaps; |
| 4284 } | 4292 } |
| 4285 return HObjectAccess(portion, offset, representation); | 4293 bool existing_inobject_property = true; |
| 4294 if (!map.is_null()) { |
| 4295 existing_inobject_property = (offset < |
| 4296 map->instance_size() - map->unused_property_fields() * kPointerSize); |
| 4297 } |
| 4298 return HObjectAccess(portion, offset, representation, Handle<String>::null(), |
| 4299 false, existing_inobject_property); |
| 4286 } | 4300 } |
| 4287 | 4301 |
| 4288 | 4302 |
| 4289 HObjectAccess HObjectAccess::ForAllocationSiteOffset(int offset) { | 4303 HObjectAccess HObjectAccess::ForAllocationSiteOffset(int offset) { |
| 4290 switch (offset) { | 4304 switch (offset) { |
| 4291 case AllocationSite::kTransitionInfoOffset: | 4305 case AllocationSite::kTransitionInfoOffset: |
| 4292 return HObjectAccess(kInobject, offset, Representation::Tagged()); | 4306 return HObjectAccess(kInobject, offset, Representation::Tagged()); |
| 4293 case AllocationSite::kNestedSiteOffset: | 4307 case AllocationSite::kNestedSiteOffset: |
| 4294 return HObjectAccess(kInobject, offset, Representation::Tagged()); | 4308 return HObjectAccess(kInobject, offset, Representation::Tagged()); |
| 4295 case AllocationSite::kPretenureDataOffset: | 4309 case AllocationSite::kPretenureDataOffset: |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4327 } else if (offset == JSObject::kMapOffset) { | 4341 } else if (offset == JSObject::kMapOffset) { |
| 4328 portion = kMaps; | 4342 portion = kMaps; |
| 4329 } | 4343 } |
| 4330 return HObjectAccess(portion, offset); | 4344 return HObjectAccess(portion, offset); |
| 4331 } | 4345 } |
| 4332 | 4346 |
| 4333 | 4347 |
| 4334 HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset, | 4348 HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset, |
| 4335 Representation representation) { | 4349 Representation representation) { |
| 4336 ASSERT(offset >= 0); | 4350 ASSERT(offset >= 0); |
| 4337 return HObjectAccess(kBackingStore, offset, representation); | 4351 return HObjectAccess(kBackingStore, offset, representation, |
| 4352 Handle<String>::null(), false, false); |
| 4338 } | 4353 } |
| 4339 | 4354 |
| 4340 | 4355 |
| 4341 HObjectAccess HObjectAccess::ForField(Handle<Map> map, | 4356 HObjectAccess HObjectAccess::ForField(Handle<Map> map, |
| 4342 LookupResult *lookup, Handle<String> name) { | 4357 LookupResult* lookup, |
| 4358 Handle<String> name) { |
| 4343 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*map)); | 4359 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*map)); |
| 4344 int index; | 4360 int index; |
| 4345 Representation representation; | 4361 Representation representation; |
| 4346 if (lookup->IsField()) { | 4362 if (lookup->IsField()) { |
| 4347 index = lookup->GetLocalFieldIndexFromMap(*map); | 4363 index = lookup->GetLocalFieldIndexFromMap(*map); |
| 4348 representation = lookup->representation(); | 4364 representation = lookup->representation(); |
| 4349 } else { | 4365 } else { |
| 4350 Map* transition = lookup->GetTransitionMapFromMap(*map); | 4366 Map* transition = lookup->GetTransitionMapFromMap(*map); |
| 4351 int descriptor = transition->LastAdded(); | 4367 int descriptor = transition->LastAdded(); |
| 4352 index = transition->instance_descriptors()->GetFieldIndex(descriptor) - | 4368 index = transition->instance_descriptors()->GetFieldIndex(descriptor) - |
| 4353 map->inobject_properties(); | 4369 map->inobject_properties(); |
| 4354 PropertyDetails details = | 4370 PropertyDetails details = |
| 4355 transition->instance_descriptors()->GetDetails(descriptor); | 4371 transition->instance_descriptors()->GetDetails(descriptor); |
| 4356 representation = details.representation(); | 4372 representation = details.representation(); |
| 4357 } | 4373 } |
| 4358 if (index < 0) { | 4374 if (index < 0) { |
| 4359 // Negative property indices are in-object properties, indexed | 4375 // Negative property indices are in-object properties, indexed |
| 4360 // from the end of the fixed part of the object. | 4376 // from the end of the fixed part of the object. |
| 4361 int offset = (index * kPointerSize) + map->instance_size(); | 4377 int offset = (index * kPointerSize) + map->instance_size(); |
| 4362 return HObjectAccess(kInobject, offset, representation, name); | 4378 return HObjectAccess(kInobject, offset, representation, name, false, true); |
| 4363 } else { | 4379 } else { |
| 4364 // Non-negative property indices are in the properties array. | 4380 // Non-negative property indices are in the properties array. |
| 4365 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; | 4381 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
| 4366 return HObjectAccess(kBackingStore, offset, representation, name); | 4382 return HObjectAccess(kBackingStore, offset, representation, name, |
| 4383 false, false); |
| 4367 } | 4384 } |
| 4368 } | 4385 } |
| 4369 | 4386 |
| 4370 | 4387 |
| 4371 HObjectAccess HObjectAccess::ForCellPayload(Isolate* isolate) { | 4388 HObjectAccess HObjectAccess::ForCellPayload(Isolate* isolate) { |
| 4372 return HObjectAccess( | 4389 return HObjectAccess( |
| 4373 kInobject, Cell::kValueOffset, Representation::Tagged(), | 4390 kInobject, Cell::kValueOffset, Representation::Tagged(), |
| 4374 Handle<String>(isolate->heap()->cell_value_string())); | 4391 Handle<String>(isolate->heap()->cell_value_string())); |
| 4375 } | 4392 } |
| 4376 | 4393 |
| 4377 | 4394 |
| 4378 void HObjectAccess::SetGVNFlags(HValue *instr, bool is_store) { | 4395 void HObjectAccess::SetGVNFlags(HValue *instr, PropertyAccessType access_type) { |
| 4379 // set the appropriate GVN flags for a given load or store instruction | 4396 // set the appropriate GVN flags for a given load or store instruction |
| 4380 if (is_store) { | 4397 if (access_type == STORE) { |
| 4381 // track dominating allocations in order to eliminate write barriers | 4398 // track dominating allocations in order to eliminate write barriers |
| 4382 instr->SetGVNFlag(kDependsOnNewSpacePromotion); | 4399 instr->SetGVNFlag(kDependsOnNewSpacePromotion); |
| 4383 instr->SetFlag(HValue::kTrackSideEffectDominators); | 4400 instr->SetFlag(HValue::kTrackSideEffectDominators); |
| 4384 } else { | 4401 } else { |
| 4385 // try to GVN loads, but don't hoist above map changes | 4402 // try to GVN loads, but don't hoist above map changes |
| 4386 instr->SetFlag(HValue::kUseGVN); | 4403 instr->SetFlag(HValue::kUseGVN); |
| 4387 instr->SetGVNFlag(kDependsOnMaps); | 4404 instr->SetGVNFlag(kDependsOnMaps); |
| 4388 } | 4405 } |
| 4389 | 4406 |
| 4390 switch (portion()) { | 4407 switch (portion()) { |
| 4391 case kArrayLengths: | 4408 case kArrayLengths: |
| 4392 instr->SetGVNFlag(is_store | 4409 instr->SetGVNFlag(access_type == STORE |
| 4393 ? kChangesArrayLengths : kDependsOnArrayLengths); | 4410 ? kChangesArrayLengths : kDependsOnArrayLengths); |
| 4394 break; | 4411 break; |
| 4395 case kStringLengths: | 4412 case kStringLengths: |
| 4396 instr->SetGVNFlag(is_store | 4413 instr->SetGVNFlag(access_type == STORE |
| 4397 ? kChangesStringLengths : kDependsOnStringLengths); | 4414 ? kChangesStringLengths : kDependsOnStringLengths); |
| 4398 break; | 4415 break; |
| 4399 case kInobject: | 4416 case kInobject: |
| 4400 instr->SetGVNFlag(is_store | 4417 instr->SetGVNFlag(access_type == STORE |
| 4401 ? kChangesInobjectFields : kDependsOnInobjectFields); | 4418 ? kChangesInobjectFields : kDependsOnInobjectFields); |
| 4402 break; | 4419 break; |
| 4403 case kDouble: | 4420 case kDouble: |
| 4404 instr->SetGVNFlag(is_store | 4421 instr->SetGVNFlag(access_type == STORE |
| 4405 ? kChangesDoubleFields : kDependsOnDoubleFields); | 4422 ? kChangesDoubleFields : kDependsOnDoubleFields); |
| 4406 break; | 4423 break; |
| 4407 case kBackingStore: | 4424 case kBackingStore: |
| 4408 instr->SetGVNFlag(is_store | 4425 instr->SetGVNFlag(access_type == STORE |
| 4409 ? kChangesBackingStoreFields : kDependsOnBackingStoreFields); | 4426 ? kChangesBackingStoreFields : kDependsOnBackingStoreFields); |
| 4410 break; | 4427 break; |
| 4411 case kElementsPointer: | 4428 case kElementsPointer: |
| 4412 instr->SetGVNFlag(is_store | 4429 instr->SetGVNFlag(access_type == STORE |
| 4413 ? kChangesElementsPointer : kDependsOnElementsPointer); | 4430 ? kChangesElementsPointer : kDependsOnElementsPointer); |
| 4414 break; | 4431 break; |
| 4415 case kMaps: | 4432 case kMaps: |
| 4416 instr->SetGVNFlag(is_store | 4433 instr->SetGVNFlag(access_type == STORE |
| 4417 ? kChangesMaps : kDependsOnMaps); | 4434 ? kChangesMaps : kDependsOnMaps); |
| 4418 break; | 4435 break; |
| 4419 case kExternalMemory: | 4436 case kExternalMemory: |
| 4420 instr->SetGVNFlag(is_store | 4437 instr->SetGVNFlag(access_type == STORE |
| 4421 ? kChangesExternalMemory : kDependsOnExternalMemory); | 4438 ? kChangesExternalMemory : kDependsOnExternalMemory); |
| 4422 break; | 4439 break; |
| 4423 } | 4440 } |
| 4424 } | 4441 } |
| 4425 | 4442 |
| 4426 | 4443 |
| 4427 void HObjectAccess::PrintTo(StringStream* stream) { | 4444 void HObjectAccess::PrintTo(StringStream* stream) { |
| 4428 stream->Add("."); | 4445 stream->Add("."); |
| 4429 | 4446 |
| 4430 switch (portion()) { | 4447 switch (portion()) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4453 break; | 4470 break; |
| 4454 case kExternalMemory: | 4471 case kExternalMemory: |
| 4455 stream->Add("[external-memory]"); | 4472 stream->Add("[external-memory]"); |
| 4456 break; | 4473 break; |
| 4457 } | 4474 } |
| 4458 | 4475 |
| 4459 stream->Add("@%d", offset()); | 4476 stream->Add("@%d", offset()); |
| 4460 } | 4477 } |
| 4461 | 4478 |
| 4462 } } // namespace v8::internal | 4479 } } // namespace v8::internal |
| OLD | NEW |