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 8102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8113 enum AllocationSiteMode { | 8113 enum AllocationSiteMode { |
8114 DONT_TRACK_ALLOCATION_SITE, | 8114 DONT_TRACK_ALLOCATION_SITE, |
8115 TRACK_ALLOCATION_SITE, | 8115 TRACK_ALLOCATION_SITE, |
8116 LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE | 8116 LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE |
8117 }; | 8117 }; |
8118 | 8118 |
8119 | 8119 |
8120 class AllocationSite: public Struct { | 8120 class AllocationSite: public Struct { |
8121 public: | 8121 public: |
8122 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024; | 8122 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024; |
| 8123 static const double kPretenureRatio; |
| 8124 static const int kPretenureMinimumCreated = 100; |
| 8125 |
| 8126 // Values for pretenure decision field. |
| 8127 enum { |
| 8128 kUndecided = 0, |
| 8129 kDontTenure = 1, |
| 8130 kTenure = 2, |
| 8131 kZombie = 3 |
| 8132 }; |
8123 | 8133 |
8124 DECL_ACCESSORS(transition_info, Object) | 8134 DECL_ACCESSORS(transition_info, Object) |
8125 // nested_site threads a list of sites that represent nested literals | 8135 // nested_site threads a list of sites that represent nested literals |
8126 // walked in a particular order. So [[1, 2], 1, 2] will have one | 8136 // walked in a particular order. So [[1, 2], 1, 2] will have one |
8127 // nested_site, but [[1, 2], 3, [4]] will have a list of two. | 8137 // nested_site, but [[1, 2], 3, [4]] will have a list of two. |
8128 DECL_ACCESSORS(nested_site, Object) | 8138 DECL_ACCESSORS(nested_site, Object) |
8129 DECL_ACCESSORS(memento_found_count, Smi) | 8139 DECL_ACCESSORS(memento_found_count, Smi) |
8130 DECL_ACCESSORS(memento_create_count, Smi) | 8140 DECL_ACCESSORS(memento_create_count, Smi) |
| 8141 // TODO(mvstanton): we don't need a whole integer to record pretenure |
| 8142 // decision. Consider sharing space with memento_found_count. |
8131 DECL_ACCESSORS(pretenure_decision, Smi) | 8143 DECL_ACCESSORS(pretenure_decision, Smi) |
8132 DECL_ACCESSORS(dependent_code, DependentCode) | 8144 DECL_ACCESSORS(dependent_code, DependentCode) |
8133 DECL_ACCESSORS(weak_next, Object) | 8145 DECL_ACCESSORS(weak_next, Object) |
8134 | 8146 |
8135 inline void Initialize(); | 8147 inline void Initialize(); |
8136 | 8148 |
8137 bool HasNestedSites() { | |
8138 return nested_site()->IsAllocationSite(); | |
8139 } | |
8140 | |
8141 // This method is expensive, it should only be called for reporting. | 8149 // This method is expensive, it should only be called for reporting. |
8142 bool IsNestedSite(); | 8150 bool IsNestedSite(); |
8143 | 8151 |
8144 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {}; | 8152 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {}; |
8145 class UnusedBits: public BitField<int, 15, 14> {}; | 8153 class UnusedBits: public BitField<int, 15, 14> {}; |
8146 class DoNotInlineBit: public BitField<bool, 29, 1> {}; | 8154 class DoNotInlineBit: public BitField<bool, 29, 1> {}; |
8147 | 8155 |
| 8156 inline void IncrementMementoFoundCount(); |
| 8157 |
| 8158 inline void IncrementMementoCreateCount(); |
| 8159 |
| 8160 PretenureFlag GetPretenureMode() { |
| 8161 int mode = pretenure_decision()->value(); |
| 8162 // Zombie objects "decide" to be untenured. |
| 8163 return (mode == kTenure) ? TENURED : NOT_TENURED; |
| 8164 } |
| 8165 |
| 8166 // The pretenuring decision is made during gc, and the zombie state allows |
| 8167 // us to recognize when an allocation site is just being kept alive because |
| 8168 // a later traversal of new space may discover AllocationMementos that point |
| 8169 // to this AllocationSite. |
| 8170 bool IsZombie() { |
| 8171 return pretenure_decision()->value() == kZombie; |
| 8172 } |
| 8173 |
| 8174 inline void MarkZombie(); |
| 8175 |
| 8176 inline bool DigestPretenuringFeedback(); |
| 8177 |
8148 ElementsKind GetElementsKind() { | 8178 ElementsKind GetElementsKind() { |
8149 ASSERT(!SitePointsToLiteral()); | 8179 ASSERT(!SitePointsToLiteral()); |
8150 int value = Smi::cast(transition_info())->value(); | 8180 int value = Smi::cast(transition_info())->value(); |
8151 return ElementsKindBits::decode(value); | 8181 return ElementsKindBits::decode(value); |
8152 } | 8182 } |
8153 | 8183 |
8154 void SetElementsKind(ElementsKind kind) { | 8184 void SetElementsKind(ElementsKind kind) { |
8155 int value = Smi::cast(transition_info())->value(); | 8185 int value = Smi::cast(transition_info())->value(); |
8156 set_transition_info(Smi::FromInt(ElementsKindBits::update(value, kind)), | 8186 set_transition_info(Smi::FromInt(ElementsKindBits::update(value, kind)), |
8157 SKIP_WRITE_BARRIER); | 8187 SKIP_WRITE_BARRIER); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8211 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset; | 8241 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset; |
8212 static const int kPointerFieldsEndOffset = kDependentCodeOffset; | 8242 static const int kPointerFieldsEndOffset = kDependentCodeOffset; |
8213 | 8243 |
8214 // For other visitors, use the fixed body descriptor below. | 8244 // For other visitors, use the fixed body descriptor below. |
8215 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, | 8245 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, |
8216 kDependentCodeOffset + kPointerSize, | 8246 kDependentCodeOffset + kPointerSize, |
8217 kSize> BodyDescriptor; | 8247 kSize> BodyDescriptor; |
8218 | 8248 |
8219 private: | 8249 private: |
8220 inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason); | 8250 inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason); |
| 8251 bool PretenuringDecisionMade() { |
| 8252 return pretenure_decision()->value() != kUndecided; |
| 8253 } |
| 8254 |
8221 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite); | 8255 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite); |
8222 }; | 8256 }; |
8223 | 8257 |
8224 | 8258 |
8225 class AllocationMemento: public Struct { | 8259 class AllocationMemento: public Struct { |
8226 public: | 8260 public: |
8227 static const int kAllocationSiteOffset = HeapObject::kHeaderSize; | 8261 static const int kAllocationSiteOffset = HeapObject::kHeaderSize; |
8228 static const int kSize = kAllocationSiteOffset + kPointerSize; | 8262 static const int kSize = kAllocationSiteOffset + kPointerSize; |
8229 | 8263 |
8230 DECL_ACCESSORS(allocation_site, Object) | 8264 DECL_ACCESSORS(allocation_site, Object) |
8231 | 8265 |
8232 bool IsValid() { return allocation_site()->IsAllocationSite(); } | 8266 bool IsValid() { |
| 8267 return allocation_site()->IsAllocationSite() && |
| 8268 !AllocationSite::cast(allocation_site())->IsZombie(); |
| 8269 } |
8233 AllocationSite* GetAllocationSite() { | 8270 AllocationSite* GetAllocationSite() { |
8234 ASSERT(IsValid()); | 8271 ASSERT(IsValid()); |
8235 return AllocationSite::cast(allocation_site()); | 8272 return AllocationSite::cast(allocation_site()); |
8236 } | 8273 } |
8237 | 8274 |
8238 DECLARE_PRINTER(AllocationMemento) | 8275 DECLARE_PRINTER(AllocationMemento) |
8239 DECLARE_VERIFIER(AllocationMemento) | 8276 DECLARE_VERIFIER(AllocationMemento) |
8240 | 8277 |
8241 // Returns NULL if no AllocationMemento is available for object. | 8278 // Returns NULL if no AllocationMemento is available for object. |
8242 static AllocationMemento* FindForJSObject(JSObject* object, | 8279 static AllocationMemento* FindForJSObject(JSObject* object, |
(...skipping 2352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10595 } else { | 10632 } else { |
10596 value &= ~(1 << bit_position); | 10633 value &= ~(1 << bit_position); |
10597 } | 10634 } |
10598 return value; | 10635 return value; |
10599 } | 10636 } |
10600 }; | 10637 }; |
10601 | 10638 |
10602 } } // namespace v8::internal | 10639 } } // namespace v8::internal |
10603 | 10640 |
10604 #endif // V8_OBJECTS_H_ | 10641 #endif // V8_OBJECTS_H_ |
OLD | NEW |