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 8104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8115 }; | 8115 }; |
8116 | 8116 |
8117 | 8117 |
8118 class AllocationSite: public Struct { | 8118 class AllocationSite: public Struct { |
8119 public: | 8119 public: |
8120 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024; | 8120 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024; |
8121 static const double kPretenureRatio; | 8121 static const double kPretenureRatio; |
8122 static const int kPretenureMinimumCreated = 100; | 8122 static const int kPretenureMinimumCreated = 100; |
8123 | 8123 |
8124 // Values for pretenure decision field. | 8124 // Values for pretenure decision field. |
8125 enum { | 8125 enum PretenureDecision { |
8126 kUndecided = 0, | 8126 kUndecided = 0, |
8127 kDontTenure = 1, | 8127 kDontTenure = 1, |
8128 kTenure = 2, | 8128 kTenure = 2, |
8129 kZombie = 3 | 8129 kZombie = 3, |
| 8130 kLastPretenureDecisionValue = kZombie |
8130 }; | 8131 }; |
8131 | 8132 |
8132 DECL_ACCESSORS(transition_info, Object) | 8133 DECL_ACCESSORS(transition_info, Object) |
8133 // nested_site threads a list of sites that represent nested literals | 8134 // nested_site threads a list of sites that represent nested literals |
8134 // walked in a particular order. So [[1, 2], 1, 2] will have one | 8135 // walked in a particular order. So [[1, 2], 1, 2] will have one |
8135 // nested_site, but [[1, 2], 3, [4]] will have a list of two. | 8136 // nested_site, but [[1, 2], 3, [4]] will have a list of two. |
8136 DECL_ACCESSORS(nested_site, Object) | 8137 DECL_ACCESSORS(nested_site, Object) |
8137 DECL_ACCESSORS(memento_found_count, Smi) | 8138 DECL_ACCESSORS(pretenure_data, Smi) |
8138 DECL_ACCESSORS(memento_create_count, Smi) | 8139 DECL_ACCESSORS(pretenure_create_count, Smi) |
8139 // TODO(mvstanton): we don't need a whole integer to record pretenure | |
8140 // decision. Consider sharing space with memento_found_count. | |
8141 DECL_ACCESSORS(pretenure_decision, Smi) | |
8142 DECL_ACCESSORS(dependent_code, DependentCode) | 8140 DECL_ACCESSORS(dependent_code, DependentCode) |
8143 DECL_ACCESSORS(weak_next, Object) | 8141 DECL_ACCESSORS(weak_next, Object) |
8144 | 8142 |
8145 inline void Initialize(); | 8143 inline void Initialize(); |
8146 | 8144 |
8147 // This method is expensive, it should only be called for reporting. | 8145 // This method is expensive, it should only be called for reporting. |
8148 bool IsNestedSite(); | 8146 bool IsNestedSite(); |
8149 | 8147 |
| 8148 // transition_info bitfields, for constructed array transition info. |
8150 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {}; | 8149 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {}; |
8151 class UnusedBits: public BitField<int, 15, 14> {}; | 8150 class UnusedBits: public BitField<int, 15, 14> {}; |
8152 class DoNotInlineBit: public BitField<bool, 29, 1> {}; | 8151 class DoNotInlineBit: public BitField<bool, 29, 1> {}; |
8153 | 8152 |
| 8153 // Bitfields for pretenure_data |
| 8154 class MementoFoundCountBits: public BitField<int, 0, 28> {}; |
| 8155 class PretenureDecisionBits: public BitField<PretenureDecision, 28, 2> {}; |
| 8156 STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue); |
| 8157 |
8154 // Increments the mementos found counter and returns true when the first | 8158 // Increments the mementos found counter and returns true when the first |
8155 // memento was found for a given allocation site. | 8159 // memento was found for a given allocation site. |
8156 inline bool IncrementMementoFoundCount(); | 8160 inline bool IncrementMementoFoundCount(); |
8157 | 8161 |
8158 inline void IncrementMementoCreateCount(); | 8162 inline void IncrementMementoCreateCount(); |
8159 | 8163 |
8160 PretenureFlag GetPretenureMode() { | 8164 PretenureFlag GetPretenureMode() { |
8161 int mode = pretenure_decision()->value(); | |
8162 // Zombie objects "decide" to be untenured. | 8165 // Zombie objects "decide" to be untenured. |
8163 return (mode == kTenure) ? TENURED : NOT_TENURED; | 8166 return (pretenure_decision() == kTenure) ? TENURED : NOT_TENURED; |
| 8167 } |
| 8168 |
| 8169 PretenureDecision pretenure_decision() { |
| 8170 int value = pretenure_data()->value(); |
| 8171 return PretenureDecisionBits::decode(value); |
| 8172 } |
| 8173 |
| 8174 void set_pretenure_decision(PretenureDecision decision) { |
| 8175 int value = pretenure_data()->value(); |
| 8176 set_pretenure_data( |
| 8177 Smi::FromInt(PretenureDecisionBits::update(value, decision)), |
| 8178 SKIP_WRITE_BARRIER); |
| 8179 } |
| 8180 |
| 8181 int memento_found_count() { |
| 8182 int value = pretenure_data()->value(); |
| 8183 return MementoFoundCountBits::decode(value); |
| 8184 } |
| 8185 |
| 8186 inline void set_memento_found_count(int count); |
| 8187 |
| 8188 int memento_create_count() { |
| 8189 return pretenure_create_count()->value(); |
| 8190 } |
| 8191 |
| 8192 void set_memento_create_count(int count) { |
| 8193 set_pretenure_create_count(Smi::FromInt(count), SKIP_WRITE_BARRIER); |
8164 } | 8194 } |
8165 | 8195 |
8166 // The pretenuring decision is made during gc, and the zombie state allows | 8196 // 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 | 8197 // 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 | 8198 // a later traversal of new space may discover AllocationMementos that point |
8169 // to this AllocationSite. | 8199 // to this AllocationSite. |
8170 bool IsZombie() { | 8200 bool IsZombie() { |
8171 return pretenure_decision()->value() == kZombie; | 8201 return pretenure_decision() == kZombie; |
8172 } | 8202 } |
8173 | 8203 |
8174 inline void MarkZombie(); | 8204 inline void MarkZombie(); |
8175 | 8205 |
8176 inline bool DigestPretenuringFeedback(); | 8206 inline bool DigestPretenuringFeedback(); |
8177 | 8207 |
8178 ElementsKind GetElementsKind() { | 8208 ElementsKind GetElementsKind() { |
8179 ASSERT(!SitePointsToLiteral()); | 8209 ASSERT(!SitePointsToLiteral()); |
8180 int value = Smi::cast(transition_info())->value(); | 8210 int value = Smi::cast(transition_info())->value(); |
8181 return ElementsKindBits::decode(value); | 8211 return ElementsKindBits::decode(value); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8219 DECLARE_VERIFIER(AllocationSite) | 8249 DECLARE_VERIFIER(AllocationSite) |
8220 | 8250 |
8221 static inline AllocationSite* cast(Object* obj); | 8251 static inline AllocationSite* cast(Object* obj); |
8222 static inline AllocationSiteMode GetMode( | 8252 static inline AllocationSiteMode GetMode( |
8223 ElementsKind boilerplate_elements_kind); | 8253 ElementsKind boilerplate_elements_kind); |
8224 static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to); | 8254 static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to); |
8225 static inline bool CanTrack(InstanceType type); | 8255 static inline bool CanTrack(InstanceType type); |
8226 | 8256 |
8227 static const int kTransitionInfoOffset = HeapObject::kHeaderSize; | 8257 static const int kTransitionInfoOffset = HeapObject::kHeaderSize; |
8228 static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize; | 8258 static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize; |
8229 static const int kMementoFoundCountOffset = kNestedSiteOffset + kPointerSize; | 8259 static const int kPretenureDataOffset = kNestedSiteOffset + kPointerSize; |
8230 static const int kMementoCreateCountOffset = | 8260 static const int kPretenureCreateCountOffset = |
8231 kMementoFoundCountOffset + kPointerSize; | 8261 kPretenureDataOffset + kPointerSize; |
8232 static const int kPretenureDecisionOffset = | |
8233 kMementoCreateCountOffset + kPointerSize; | |
8234 static const int kDependentCodeOffset = | 8262 static const int kDependentCodeOffset = |
8235 kPretenureDecisionOffset + kPointerSize; | 8263 kPretenureCreateCountOffset + kPointerSize; |
8236 static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize; | 8264 static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize; |
8237 static const int kSize = kWeakNextOffset + kPointerSize; | 8265 static const int kSize = kWeakNextOffset + kPointerSize; |
8238 | 8266 |
8239 // During mark compact we need to take special care for the dependent code | 8267 // During mark compact we need to take special care for the dependent code |
8240 // field. | 8268 // field. |
8241 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset; | 8269 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset; |
8242 static const int kPointerFieldsEndOffset = kDependentCodeOffset; | 8270 static const int kPointerFieldsEndOffset = kDependentCodeOffset; |
8243 | 8271 |
8244 // For other visitors, use the fixed body descriptor below. | 8272 // For other visitors, use the fixed body descriptor below. |
8245 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, | 8273 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, |
8246 kDependentCodeOffset + kPointerSize, | 8274 kDependentCodeOffset + kPointerSize, |
8247 kSize> BodyDescriptor; | 8275 kSize> BodyDescriptor; |
8248 | 8276 |
8249 private: | 8277 private: |
8250 inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason); | 8278 inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason); |
8251 bool PretenuringDecisionMade() { | 8279 bool PretenuringDecisionMade() { |
8252 return pretenure_decision()->value() != kUndecided; | 8280 return pretenure_decision() != kUndecided; |
8253 } | 8281 } |
8254 | 8282 |
8255 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite); | 8283 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite); |
8256 }; | 8284 }; |
8257 | 8285 |
8258 | 8286 |
8259 class AllocationMemento: public Struct { | 8287 class AllocationMemento: public Struct { |
8260 public: | 8288 public: |
8261 static const int kAllocationSiteOffset = HeapObject::kHeaderSize; | 8289 static const int kAllocationSiteOffset = HeapObject::kHeaderSize; |
8262 static const int kSize = kAllocationSiteOffset + kPointerSize; | 8290 static const int kSize = kAllocationSiteOffset + kPointerSize; |
(...skipping 2364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10627 } else { | 10655 } else { |
10628 value &= ~(1 << bit_position); | 10656 value &= ~(1 << bit_position); |
10629 } | 10657 } |
10630 return value; | 10658 return value; |
10631 } | 10659 } |
10632 }; | 10660 }; |
10633 | 10661 |
10634 } } // namespace v8::internal | 10662 } } // namespace v8::internal |
10635 | 10663 |
10636 #endif // V8_OBJECTS_H_ | 10664 #endif // V8_OBJECTS_H_ |
OLD | NEW |