Chromium Code Reviews| Index: src/hydrogen-instructions.cc |
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
| index fc57aa879c68111e4158f7db07ebe685c2790110..150feb05a61d8d58bbd542552d6090d453072e48 100644 |
| --- a/src/hydrogen-instructions.cc |
| +++ b/src/hydrogen-instructions.cc |
| @@ -2464,7 +2464,7 @@ void HParameter::PrintDataTo(StringStream* stream) { |
| void HLoadNamedField::PrintDataTo(StringStream* stream) { |
| object()->PrintNameTo(stream); |
| - stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : ""); |
| + access_.PrintTo(stream); |
| if (HasTypeCheck()) { |
| stream->Add(" "); |
| typecheck()->PrintNameTo(stream); |
| @@ -2757,11 +2757,9 @@ void HStoreNamedGeneric::PrintDataTo(StringStream* stream) { |
| void HStoreNamedField::PrintDataTo(StringStream* stream) { |
| object()->PrintNameTo(stream); |
| - stream->Add("."); |
| - stream->Add(*String::cast(*name())->ToCString()); |
| + access_.PrintTo(stream); |
| stream->Add(" = "); |
| value()->PrintNameTo(stream); |
| - stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : ""); |
| if (NeedsWriteBarrier()) { |
| stream->Add(" (write-barrier)"); |
| } |
| @@ -3628,4 +3626,137 @@ void HCheckFunction::Verify() { |
| #endif |
| + |
| +HObjectAccess HObjectAccess::For(bool is_inobject, int offset, |
| + Handle<String> name) { |
| + return HObjectAccess(is_inobject ? kInobject : kBackingStore, offset, name); |
| +} |
| + |
| + |
| +HObjectAccess HObjectAccess::ForFixedArrayOffset(int offset) { |
| + return HObjectAccess(kInobject, offset); |
|
danno
2013/05/08 15:40:18
If think you might want to check offset == FixedAr
titzer
2013/05/13 11:23:19
Done.
|
| +} |
| + |
| + |
| +HObjectAccess HObjectAccess::ForJSObjectOffset(int offset, |
| + Handle<String> name) { |
| + |
| + ASSERT(offset >= 0); |
| + Portion portion = kInobject; |
| + |
| + if (offset == JSObject::kElementsOffset) { |
| + portion = kElementsPointer; |
| + } else if (offset == JSObject::kMapOffset) { |
| + portion = kMaps; |
| + } |
| + return HObjectAccess(portion, offset, name); |
| +} |
| + |
| + |
| +HObjectAccess HObjectAccess::ForJSArrayOffset(int offset, |
| + Handle<String> name) { |
| + |
| + ASSERT(offset >= 0); |
| + Portion portion = kInobject; |
| + |
| + if (offset == JSObject::kElementsOffset) { |
| + portion = kElementsPointer; |
| + } else if (offset == JSArray::kLengthOffset) { |
| + portion = kArrayLengths; |
| + } else if (offset == JSObject::kMapOffset) { |
| + portion = kMaps; |
| + } |
| + return HObjectAccess(portion, offset, name); |
| +} |
| + |
| + |
| +HObjectAccess HObjectAccess::ForField(Handle<Map> map, |
| + LookupResult *lookup, Handle<String> name) { |
| + ASSERT(lookup->IsField() || lookup->IsTransitionToField(*map)); |
| + int index; |
| + if (lookup->IsField()) { |
| + index = lookup->GetLocalFieldIndexFromMap(*map); |
| + } else { |
| + Map* transition = lookup->GetTransitionMapFromMap(*map); |
| + int descriptor = transition->LastAdded(); |
| + index = transition->instance_descriptors()->GetFieldIndex(descriptor) - |
| + map->inobject_properties(); |
| + } |
| + if (index < 0) { |
| + // Negative property indices are in-object properties, indexed |
| + // from the end of the fixed part of the object. |
| + int offset = (index * kPointerSize) + map->instance_size(); |
| + return HObjectAccess(kInobject, offset); |
| + } else { |
| + // Non-negative property indices are in the properties array. |
| + int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
| + return HObjectAccess(kBackingStore, offset, name); |
| + } |
| +} |
| + |
| + |
| +void HObjectAccess::SetGVNFlags(HValue *instr, bool is_store) { |
| + // set the appropriate GVN flags for a given load or store instruction |
| + if (is_store) { |
| + // track dominating allocations in order to eliminate write barriers |
| + instr->SetGVNFlag(kDependsOnNewSpacePromotion); |
| + instr->SetFlag(HValue::kTrackSideEffectDominators); |
| + } else { |
| + // try to GVN loads, but don't hoist have map changes |
| + instr->SetFlag(HValue::kUseGVN); |
| + instr->SetGVNFlag(kDependsOnMaps); |
| + } |
| + |
| + switch (portion_) { |
| + case kArrayLengths: |
| + instr->SetGVNFlag(is_store |
| + ? kChangesArrayLengths : kDependsOnArrayLengths); |
| + break; |
| + case kInobject: |
| + instr->SetGVNFlag(is_store |
| + ? kChangesInobjectFields : kDependsOnInobjectFields); |
| + break; |
| + case kBackingStore: |
| + instr->SetGVNFlag(is_store |
| + ? kChangesBackingStoreFields : kDependsOnBackingStoreFields); |
| + break; |
| + case kElementsPointer: |
| + instr->SetGVNFlag(is_store |
| + ? kChangesElementsPointer : kDependsOnElementsPointer); |
| + break; |
| + case kMaps: |
| + instr->SetGVNFlag(is_store |
| + ? kChangesMaps : kDependsOnMaps); |
| + break; |
| + } |
| +} |
| + |
| + |
| +void HObjectAccess::PrintTo(StringStream* stream) { |
| + stream->Add(".@%d", offset_); |
| + |
| + // several portions have well-known names |
| + switch (portion_) { |
| + case kArrayLengths: |
| + stream->Add("[array-length]"); |
| + return; |
| + case kElementsPointer: |
| + stream->Add("[elements]"); |
| + return; |
| + case kMaps: |
| + stream->Add("[map]"); |
| + return; |
| + case kInobject: |
| + stream->Add("[in-object]"); |
| + break; // also print the name if possible |
| + } |
| + |
| + // otherwise, add the name if it is known |
| + if (!name_.is_null()) { |
| + stream->Add(" name["); |
| + stream->Add(*String::cast(*name_)->ToCString()); |
| + stream->Add("]"); |
| + } |
| +} |
| + |
| } } // namespace v8::internal |