Index: src/hydrogen-instructions.cc |
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
index 70e2395574747085a8a554cc0a84d00eecd81390..07f521f1b7b82ca303064ba132868d0ea5f8c729 100644 |
--- a/src/hydrogen-instructions.cc |
+++ b/src/hydrogen-instructions.cc |
@@ -3650,7 +3650,120 @@ void HCheckFunction::Verify() { |
HInstruction::Verify(); |
ASSERT(HasNoUses()); |
} |
- |
danno
2013/05/06 15:53:06
Stray whitespace removal, please add back.
titzer
2013/05/07 17:51:03
Done.
|
#endif |
+ |
+// global accesses that can be shared across instructions |
+HObjectAccess elements_pointer_access_( |
+ HObjectAccess::kElementsPointer, JSObject::kElementsOffset); |
+HObjectAccess array_length_access_( |
+ HObjectAccess::kArrayLengths, JSArray::kLengthOffset); |
+HObjectAccess fixed_array_length_access_( |
+ HObjectAccess::kInobject, FixedArray::kLengthOffset); |
+HObjectAccess map_access_( |
+ HObjectAccess::kMaps, JSObject::kMapOffset); |
+ |
+ |
+HObjectAccess* HObjectAccess::ForElementsPointer() { |
+ return &elements_pointer_access_; |
+} |
+ |
+ |
+HObjectAccess* HObjectAccess::ForArrayLength() { |
+ return &array_length_access_; |
+} |
+ |
+ |
+HObjectAccess* HObjectAccess::ForFixedArrayLength() { |
+ return &fixed_array_length_access_; |
+} |
+ |
+ |
+HObjectAccess* HObjectAccess::ForMap() { |
+ return &map_access_; |
+} |
+ |
danno
2013/05/06 15:53:06
nit: two newlines
titzer
2013/05/07 17:51:03
Done.
|
+HObjectAccess* HObjectAccess::ForInobjectOffset(Zone *zone, int offset, |
+ Handle<String> name) { |
+ |
+ ASSERT(offset >= 0); |
+ Portion portion = kInobject; |
+ |
+ if (offset == JSObject::kElementsOffset) { |
+ portion = kElementsPointer; |
+ } else if (offset == JSArray::kLengthOffset) { |
+ portion = kArrayLengths; // XXX: only true for arrays? |
+ } else if (offset == JSObject::kMapOffset) { |
+ portion = kMaps; |
+ } |
+ return new(zone) HObjectAccess(portion, offset, name); |
+} |
+ |
danno
2013/05/06 15:53:06
nit: two lines
titzer
2013/05/07 17:51:03
Done.
|
+HObjectAccess* HObjectAccess::ForOffset(Zone *zone, int offset, |
+ Handle<String> name) { |
+ return new(zone) HObjectAccess(kInobject, offset, name); |
+} |
+ |
danno
2013/05/06 15:53:06
nit: two lines
titzer
2013/05/07 17:51:03
Done.
|
+HObjectAccess* HObjectAccess::ForField(Zone *zone, 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 new(zone) HObjectAccess(HObjectAccess::kInobject, offset); |
+ } else { |
+ // Non-negative property indices are in the properties array. |
+ int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
+ return new(zone) |
+ HObjectAccess(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; |
+ } |
+} |
+ |
} } // namespace v8::internal |