Chromium Code Reviews| 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 2446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2457 } | 2457 } |
| 2458 | 2458 |
| 2459 | 2459 |
| 2460 void HParameter::PrintDataTo(StringStream* stream) { | 2460 void HParameter::PrintDataTo(StringStream* stream) { |
| 2461 stream->Add("%u", index()); | 2461 stream->Add("%u", index()); |
| 2462 } | 2462 } |
| 2463 | 2463 |
| 2464 | 2464 |
| 2465 void HLoadNamedField::PrintDataTo(StringStream* stream) { | 2465 void HLoadNamedField::PrintDataTo(StringStream* stream) { |
| 2466 object()->PrintNameTo(stream); | 2466 object()->PrintNameTo(stream); |
| 2467 stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : ""); | 2467 access_.PrintTo(stream); |
| 2468 if (HasTypeCheck()) { | 2468 if (HasTypeCheck()) { |
| 2469 stream->Add(" "); | 2469 stream->Add(" "); |
| 2470 typecheck()->PrintNameTo(stream); | 2470 typecheck()->PrintNameTo(stream); |
| 2471 } | 2471 } |
| 2472 } | 2472 } |
| 2473 | 2473 |
| 2474 | 2474 |
| 2475 // Returns true if an instance of this map can never find a property with this | 2475 // Returns true if an instance of this map can never find a property with this |
| 2476 // name in its prototype chain. This means all prototypes up to the top are | 2476 // name in its prototype chain. This means all prototypes up to the top are |
| 2477 // fast and don't have the name in them. It would be good if we could optimize | 2477 // fast and don't have the name in them. It would be good if we could optimize |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2750 stream->Add("."); | 2750 stream->Add("."); |
| 2751 ASSERT(name()->IsString()); | 2751 ASSERT(name()->IsString()); |
| 2752 stream->Add(*String::cast(*name())->ToCString()); | 2752 stream->Add(*String::cast(*name())->ToCString()); |
| 2753 stream->Add(" = "); | 2753 stream->Add(" = "); |
| 2754 value()->PrintNameTo(stream); | 2754 value()->PrintNameTo(stream); |
| 2755 } | 2755 } |
| 2756 | 2756 |
| 2757 | 2757 |
| 2758 void HStoreNamedField::PrintDataTo(StringStream* stream) { | 2758 void HStoreNamedField::PrintDataTo(StringStream* stream) { |
| 2759 object()->PrintNameTo(stream); | 2759 object()->PrintNameTo(stream); |
| 2760 stream->Add("."); | 2760 access_.PrintTo(stream); |
| 2761 stream->Add(*String::cast(*name())->ToCString()); | |
| 2762 stream->Add(" = "); | 2761 stream->Add(" = "); |
| 2763 value()->PrintNameTo(stream); | 2762 value()->PrintNameTo(stream); |
| 2764 stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : ""); | |
| 2765 if (NeedsWriteBarrier()) { | 2763 if (NeedsWriteBarrier()) { |
| 2766 stream->Add(" (write-barrier)"); | 2764 stream->Add(" (write-barrier)"); |
| 2767 } | 2765 } |
| 2768 if (!transition().is_null()) { | 2766 if (!transition().is_null()) { |
| 2769 stream->Add(" (transition map %p)", *transition()); | 2767 stream->Add(" (transition map %p)", *transition()); |
| 2770 } | 2768 } |
| 2771 } | 2769 } |
| 2772 | 2770 |
| 2773 | 2771 |
| 2774 void HStoreKeyed::PrintDataTo(StringStream* stream) { | 2772 void HStoreKeyed::PrintDataTo(StringStream* stream) { |
| (...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3621 } | 3619 } |
| 3622 | 3620 |
| 3623 | 3621 |
| 3624 void HCheckFunction::Verify() { | 3622 void HCheckFunction::Verify() { |
| 3625 HInstruction::Verify(); | 3623 HInstruction::Verify(); |
| 3626 ASSERT(HasNoUses()); | 3624 ASSERT(HasNoUses()); |
| 3627 } | 3625 } |
| 3628 | 3626 |
| 3629 #endif | 3627 #endif |
| 3630 | 3628 |
| 3629 | |
| 3630 HObjectAccess HObjectAccess::ForFixedArrayOffset(int offset) { | |
| 3631 ASSERT(offset >= 0); | |
| 3632 if (offset == FixedArray::kLengthOffset) return ForFixedArrayLength(); | |
| 3633 return HObjectAccess(kInobject, offset); | |
|
danno
2013/05/10 15:59:19
How about handling the map at offset zero like oth
titzer
2013/05/13 11:23:19
Unfortunately we use this variant to construct a d
danno
2013/05/13 15:44:32
OK, then you will have to be very careful here. Th
titzer
2013/05/14 09:26:19
I've renamed this to ForFixedArrayHeader, and only
| |
| 3634 } | |
| 3635 | |
| 3636 | |
| 3637 HObjectAccess HObjectAccess::ForJSObjectOffset(int offset, | |
| 3638 Handle<String> name) { | |
| 3639 ASSERT(offset >= 0); | |
|
danno
2013/05/10 15:59:19
I think this assert is bogus (maps?)
titzer
2013/05/13 11:23:19
Maps seem to be at offset 0 on ia32. Is this true
danno
2013/05/13 15:44:32
Ah, yes, it's not -1, it's still untagged at this
| |
| 3640 Portion portion = kInobject; | |
| 3641 | |
| 3642 if (offset == JSObject::kElementsOffset) { | |
| 3643 portion = kElementsPointer; | |
| 3644 } else if (offset == JSObject::kMapOffset) { | |
| 3645 portion = kMaps; | |
| 3646 } | |
| 3647 return HObjectAccess(portion, offset, name); | |
| 3648 } | |
| 3649 | |
| 3650 | |
| 3651 HObjectAccess HObjectAccess::ForJSArrayOffset(int offset, | |
| 3652 Handle<String> name) { | |
| 3653 ASSERT(offset >= 0); | |
|
danno
2013/05/10 15:59:19
I think this assert is bogus (maps?)
danno
2013/05/13 15:44:32
Yeah, ignore this
On 2013/05/10 15:59:19, danno wr
| |
| 3654 Portion portion = kInobject; | |
| 3655 | |
| 3656 if (offset == JSObject::kElementsOffset) { | |
| 3657 portion = kElementsPointer; | |
| 3658 } else if (offset == JSArray::kLengthOffset) { | |
| 3659 portion = kArrayLengths; | |
| 3660 } else if (offset == JSObject::kMapOffset) { | |
| 3661 portion = kMaps; | |
| 3662 } | |
| 3663 return HObjectAccess(portion, offset, name); | |
| 3664 } | |
| 3665 | |
| 3666 | |
| 3667 HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset, | |
| 3668 Handle<String> name) { | |
| 3669 ASSERT(offset >= 0); | |
| 3670 return HObjectAccess(kBackingStore, offset, name); | |
| 3671 } | |
| 3672 | |
| 3673 | |
| 3674 | |
| 3675 HObjectAccess HObjectAccess::ForField(Handle<Map> map, | |
| 3676 LookupResult *lookup, Handle<String> name) { | |
| 3677 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*map)); | |
| 3678 int index; | |
| 3679 if (lookup->IsField()) { | |
| 3680 index = lookup->GetLocalFieldIndexFromMap(*map); | |
| 3681 } else { | |
| 3682 Map* transition = lookup->GetTransitionMapFromMap(*map); | |
| 3683 int descriptor = transition->LastAdded(); | |
| 3684 index = transition->instance_descriptors()->GetFieldIndex(descriptor) - | |
| 3685 map->inobject_properties(); | |
| 3686 } | |
| 3687 if (index < 0) { | |
| 3688 // Negative property indices are in-object properties, indexed | |
| 3689 // from the end of the fixed part of the object. | |
| 3690 int offset = (index * kPointerSize) + map->instance_size(); | |
| 3691 return HObjectAccess(kInobject, offset); | |
| 3692 } else { | |
| 3693 // Non-negative property indices are in the properties array. | |
| 3694 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; | |
| 3695 return HObjectAccess(kBackingStore, offset, name); | |
| 3696 } | |
| 3697 } | |
| 3698 | |
| 3699 | |
| 3700 void HObjectAccess::SetGVNFlags(HValue *instr, bool is_store) { | |
| 3701 // set the appropriate GVN flags for a given load or store instruction | |
| 3702 if (is_store) { | |
| 3703 // track dominating allocations in order to eliminate write barriers | |
| 3704 instr->SetGVNFlag(kDependsOnNewSpacePromotion); | |
| 3705 instr->SetFlag(HValue::kTrackSideEffectDominators); | |
| 3706 } else { | |
| 3707 // try to GVN loads, but don't hoist have map changes | |
| 3708 instr->SetFlag(HValue::kUseGVN); | |
| 3709 instr->SetGVNFlag(kDependsOnMaps); | |
| 3710 } | |
| 3711 | |
| 3712 switch (portion_) { | |
| 3713 case kArrayLengths: | |
| 3714 instr->SetGVNFlag(is_store | |
| 3715 ? kChangesArrayLengths : kDependsOnArrayLengths); | |
| 3716 break; | |
| 3717 case kInobject: | |
| 3718 instr->SetGVNFlag(is_store | |
| 3719 ? kChangesInobjectFields : kDependsOnInobjectFields); | |
| 3720 break; | |
| 3721 case kBackingStore: | |
| 3722 instr->SetGVNFlag(is_store | |
| 3723 ? kChangesBackingStoreFields : kDependsOnBackingStoreFields); | |
| 3724 break; | |
| 3725 case kElementsPointer: | |
| 3726 instr->SetGVNFlag(is_store | |
| 3727 ? kChangesElementsPointer : kDependsOnElementsPointer); | |
| 3728 break; | |
| 3729 case kMaps: | |
| 3730 instr->SetGVNFlag(is_store | |
| 3731 ? kChangesMaps : kDependsOnMaps); | |
| 3732 break; | |
| 3733 } | |
| 3734 } | |
| 3735 | |
| 3736 | |
| 3737 void HObjectAccess::PrintTo(StringStream* stream) { | |
| 3738 stream->Add(".@%d", offset_); | |
|
danno
2013/05/13 15:44:32
I'd prefer the output of the form (it's the way it
titzer
2013/05/14 09:26:19
Done.
| |
| 3739 | |
| 3740 // several portions have well-known names | |
| 3741 switch (portion_) { | |
| 3742 case kArrayLengths: | |
| 3743 stream->Add("[array-length]"); | |
| 3744 return; | |
| 3745 case kElementsPointer: | |
| 3746 stream->Add("[elements]"); | |
| 3747 return; | |
| 3748 case kMaps: | |
| 3749 stream->Add("[map]"); | |
| 3750 return; | |
| 3751 case kInobject: | |
| 3752 stream->Add("[in-object]"); | |
|
danno
2013/05/13 15:44:32
Shouldn't you only print this if there is no name,
titzer
2013/05/14 09:26:19
I believe the old code would print [in-object] or
| |
| 3753 break; // also print the name if possible | |
| 3754 } | |
| 3755 | |
| 3756 // otherwise, add the name if it is known | |
| 3757 if (!name_.is_null()) { | |
|
danno
2013/05/13 15:44:32
Seems like this should be mutually exclusive with
titzer
2013/05/14 09:26:19
Currently, yes, but I'd rather not put an assert i
| |
| 3758 stream->Add(" name["); | |
| 3759 stream->Add(*String::cast(*name_)->ToCString()); | |
|
danno
2013/05/13 15:44:32
See above, please use existing JavaScript-like syn
titzer
2013/05/14 09:26:19
Done.
| |
| 3760 stream->Add("]"); | |
| 3761 } | |
| 3762 } | |
| 3763 | |
| 3631 } } // namespace v8::internal | 3764 } } // namespace v8::internal |
| OLD | NEW |