5 #ifndef V8_OBJECTS_ALLOCATION_SITE_INL_H_ 6 #define V8_OBJECTS_ALLOCATION_SITE_INL_H_ 8 #include "src/objects/allocation-site.h" 10 #include "src/heap/heap-inl.h" 11 #include "src/objects/js-objects-inl.h" 14 #include "src/objects/object-macros.h" 19 CAST_ACCESSOR(AllocationMemento)
20 CAST_ACCESSOR(AllocationSite)
22 ACCESSORS(AllocationSite, transition_info_or_boilerplate, Object,
23 kTransitionInfoOrBoilerplateOffset)
24 ACCESSORS(AllocationSite, nested_site, Object, kNestedSiteOffset)
25 INT32_ACCESSORS(AllocationSite, pretenure_data, kPretenureDataOffset)
26 INT32_ACCESSORS(AllocationSite, pretenure_create_count,
27 kPretenureCreateCountOffset)
28 ACCESSORS(AllocationSite, dependent_code, DependentCode, kDependentCodeOffset)
29 ACCESSORS_CHECKED(AllocationSite, weak_next, Object, kWeakNextOffset,
31 ACCESSORS(AllocationMemento, allocation_site, Object, kAllocationSiteOffset)
33 JSObject* AllocationSite::boilerplate()
const {
34 DCHECK(PointsToLiteral());
35 return JSObject::cast(transition_info_or_boilerplate());
38 void AllocationSite::set_boilerplate(JSObject*
object, WriteBarrierMode mode) {
39 set_transition_info_or_boilerplate(
object, mode);
42 int AllocationSite::transition_info()
const {
43 DCHECK(!PointsToLiteral());
44 return Smi::cast(transition_info_or_boilerplate())->value();
47 void AllocationSite::set_transition_info(
int value) {
48 DCHECK(!PointsToLiteral());
49 set_transition_info_or_boilerplate(Smi::FromInt(value), SKIP_WRITE_BARRIER);
52 bool AllocationSite::HasWeakNext()
const {
53 return map() == GetReadOnlyRoots().allocation_site_map();
56 void AllocationSite::Initialize() {
57 set_transition_info_or_boilerplate(Smi::kZero);
58 SetElementsKind(GetInitialFastElementsKind());
59 set_nested_site(Smi::kZero);
60 set_pretenure_data(0);
61 set_pretenure_create_count(0);
63 DependentCode::cast(GetReadOnlyRoots().empty_weak_fixed_array()),
67 bool AllocationSite::IsZombie()
const {
68 return pretenure_decision() == kZombie;
71 bool AllocationSite::IsMaybeTenure()
const {
72 return pretenure_decision() == kMaybeTenure;
75 bool AllocationSite::PretenuringDecisionMade()
const {
76 return pretenure_decision() != kUndecided;
79 void AllocationSite::MarkZombie() {
82 set_pretenure_decision(kZombie);
85 ElementsKind AllocationSite::GetElementsKind()
const {
86 return ElementsKindBits::decode(transition_info());
89 void AllocationSite::SetElementsKind(ElementsKind kind) {
90 set_transition_info(ElementsKindBits::update(transition_info(), kind));
93 bool AllocationSite::CanInlineCall()
const {
94 return DoNotInlineBit::decode(transition_info()) == 0;
97 void AllocationSite::SetDoNotInlineCall() {
98 set_transition_info(DoNotInlineBit::update(transition_info(),
true));
101 bool AllocationSite::PointsToLiteral()
const {
102 Object* raw_value = transition_info_or_boilerplate();
103 DCHECK_EQ(!raw_value->IsSmi(),
104 raw_value->IsJSArray() || raw_value->IsJSObject());
105 return !raw_value->IsSmi();
110 bool AllocationSite::ShouldTrack(ElementsKind boilerplate_elements_kind) {
111 return IsSmiElementsKind(boilerplate_elements_kind);
114 inline bool AllocationSite::CanTrack(InstanceType type) {
115 if (FLAG_allocation_site_pretenuring) {
118 return type == JS_ARRAY_TYPE || type == JS_OBJECT_TYPE;
120 return type == JS_ARRAY_TYPE;
123 AllocationSite::PretenureDecision AllocationSite::pretenure_decision()
const {
124 return PretenureDecisionBits::decode(pretenure_data());
127 void AllocationSite::set_pretenure_decision(PretenureDecision decision) {
128 int32_t value = pretenure_data();
129 set_pretenure_data(PretenureDecisionBits::update(value, decision));
132 bool AllocationSite::deopt_dependent_code()
const {
133 return DeoptDependentCodeBit::decode(pretenure_data());
136 void AllocationSite::set_deopt_dependent_code(
bool deopt) {
137 int32_t value = pretenure_data();
138 set_pretenure_data(DeoptDependentCodeBit::update(value, deopt));
141 int AllocationSite::memento_found_count()
const {
142 return MementoFoundCountBits::decode(pretenure_data());
145 inline void AllocationSite::set_memento_found_count(
int count) {
146 int32_t value = pretenure_data();
149 DCHECK((GetHeap()->MaxSemiSpaceSize() /
150 (Heap::kMinObjectSizeInTaggedWords * kTaggedSize +
151 AllocationMemento::kSize)) < MementoFoundCountBits::kMax);
152 DCHECK_LT(count, MementoFoundCountBits::kMax);
153 set_pretenure_data(MementoFoundCountBits::update(value, count));
156 int AllocationSite::memento_create_count()
const {
157 return pretenure_create_count();
160 void AllocationSite::set_memento_create_count(
int count) {
161 set_pretenure_create_count(count);
164 bool AllocationSite::IncrementMementoFoundCount(
int increment) {
165 if (IsZombie())
return false;
167 int value = memento_found_count();
168 set_memento_found_count(value + increment);
169 return memento_found_count() >= kPretenureMinimumCreated;
172 inline void AllocationSite::IncrementMementoCreateCount() {
173 DCHECK(FLAG_allocation_site_pretenuring);
174 int value = memento_create_count();
175 set_memento_create_count(value + 1);
178 bool AllocationMemento::IsValid()
const {
179 return allocation_site()->IsAllocationSite() &&
180 !AllocationSite::cast(allocation_site())->IsZombie();
183 AllocationSite* AllocationMemento::GetAllocationSite()
const {
185 return AllocationSite::cast(allocation_site());
188 Address AllocationMemento::GetAllocationSiteUnchecked()
const {
189 return reinterpret_cast<Address
>(allocation_site());
195 #include "src/objects/object-macros-undef.h" 197 #endif // V8_OBJECTS_ALLOCATION_SITE_INL_H_