Index: src/hydrogen-instructions.cc |
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
index fc57aa879c68111e4158f7db07ebe685c2790110..37f7d425b786fc7233b6ba1323ea74c21314f372 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,139 @@ void HCheckFunction::Verify() { |
#endif |
+ |
+HObjectAccess HObjectAccess::ForFixedArrayOffset(int offset) { |
+ ASSERT(offset >= 0); |
+ if (offset == FixedArray::kLengthOffset) return ForFixedArrayLength(); |
+ 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
|
+} |
+ |
+ |
+HObjectAccess HObjectAccess::ForJSObjectOffset(int offset, |
+ Handle<String> name) { |
+ 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
|
+ 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); |
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
|
+ 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::ForBackingStoreOffset(int offset, |
+ Handle<String> name) { |
+ ASSERT(offset >= 0); |
+ return HObjectAccess(kBackingStore, 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_); |
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.
|
+ |
+ // 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]"); |
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
|
+ break; // also print the name if possible |
+ } |
+ |
+ // otherwise, add the name if it is known |
+ 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
|
+ stream->Add(" name["); |
+ 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.
|
+ stream->Add("]"); |
+ } |
+} |
+ |
} } // namespace v8::internal |