Index: src/objects-inl.h |
diff --git a/src/objects-inl.h b/src/objects-inl.h |
index 27c969564d094cd326b620f9f55a751b00b78d38..16676202cf08b02c1dd65011a4c4e774ab3b7e3d 100644 |
--- a/src/objects-inl.h |
+++ b/src/objects-inl.h |
@@ -1107,6 +1107,44 @@ bool Object::IsMinusZero() const { |
} |
+Representation Object::OptimalRepresentation() { |
+ if (!FLAG_track_fields) return Representation::Tagged(); |
+ if (IsSmi()) { |
+ return Representation::Smi(); |
+ } else if (FLAG_track_double_fields && IsHeapNumber()) { |
+ return Representation::Double(); |
+ } else if (FLAG_track_computed_fields && IsUninitialized()) { |
+ return Representation::None(); |
+ } else if (FLAG_track_heap_object_fields) { |
+ DCHECK(IsHeapObject()); |
+ return Representation::HeapObject(); |
+ } else { |
+ return Representation::Tagged(); |
+ } |
+} |
+ |
+ |
+ElementsKind Object::OptimalElementsKind() { |
+ if (IsSmi()) return FAST_SMI_ELEMENTS; |
+ if (IsNumber()) return FAST_DOUBLE_ELEMENTS; |
+ return FAST_ELEMENTS; |
+} |
+ |
+ |
+bool Object::FitsRepresentation(Representation representation) { |
+ if (FLAG_track_fields && representation.IsNone()) { |
+ return false; |
+ } else if (FLAG_track_fields && representation.IsSmi()) { |
+ return IsSmi(); |
+ } else if (FLAG_track_double_fields && representation.IsDouble()) { |
+ return IsMutableHeapNumber() || IsNumber(); |
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
+ return IsHeapObject(); |
+ } |
+ return true; |
+} |
+ |
+ |
MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate, |
Handle<Object> object) { |
return ToObject( |
@@ -1292,31 +1330,6 @@ Object** HeapObject::RawField(HeapObject* obj, int byte_offset) { |
} |
-int Smi::value() const { |
- return Internals::SmiValue(this); |
-} |
- |
- |
-Smi* Smi::FromInt(int value) { |
- DCHECK(Smi::IsValid(value)); |
- return reinterpret_cast<Smi*>(Internals::IntToSmi(value)); |
-} |
- |
- |
-Smi* Smi::FromIntptr(intptr_t value) { |
- DCHECK(Smi::IsValid(value)); |
- int smi_shift_bits = kSmiTagSize + kSmiShiftSize; |
- return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag); |
-} |
- |
- |
-bool Smi::IsValid(intptr_t value) { |
- bool result = Internals::IsValidSmi(value); |
- DCHECK_EQ(result, value >= kMinValue && value <= kMaxValue); |
- return result; |
-} |
- |
- |
MapWord MapWord::FromMap(const Map* map) { |
return MapWord(reinterpret_cast<uintptr_t>(map)); |
} |
@@ -1440,17 +1453,6 @@ void HeapObject::synchronized_set_map_word(MapWord map_word) { |
} |
-HeapObject* HeapObject::FromAddress(Address address) { |
- DCHECK_TAG_ALIGNED(address); |
- return reinterpret_cast<HeapObject*>(address + kHeapObjectTag); |
-} |
- |
- |
-Address HeapObject::address() { |
- return reinterpret_cast<Address>(this) - kHeapObjectTag; |
-} |
- |
- |
int HeapObject::Size() { |
return SizeFromMap(map()); |
} |
@@ -1745,6 +1747,19 @@ void AllocationSite::Initialize() { |
} |
+bool AllocationSite::IsZombie() { return pretenure_decision() == kZombie; } |
+ |
+ |
+bool AllocationSite::IsMaybeTenure() { |
+ return pretenure_decision() == kMaybeTenure; |
+} |
+ |
+ |
+bool AllocationSite::PretenuringDecisionMade() { |
+ return pretenure_decision() != kUndecided; |
+} |
+ |
+ |
void AllocationSite::MarkZombie() { |
DCHECK(!IsZombie()); |
Initialize(); |
@@ -1752,6 +1767,41 @@ void AllocationSite::MarkZombie() { |
} |
+ElementsKind AllocationSite::GetElementsKind() { |
+ DCHECK(!SitePointsToLiteral()); |
+ int value = Smi::cast(transition_info())->value(); |
+ return ElementsKindBits::decode(value); |
+} |
+ |
+ |
+void AllocationSite::SetElementsKind(ElementsKind kind) { |
+ int value = Smi::cast(transition_info())->value(); |
+ set_transition_info(Smi::FromInt(ElementsKindBits::update(value, kind)), |
+ SKIP_WRITE_BARRIER); |
+} |
+ |
+ |
+bool AllocationSite::CanInlineCall() { |
+ int value = Smi::cast(transition_info())->value(); |
+ return DoNotInlineBit::decode(value) == 0; |
+} |
+ |
+ |
+void AllocationSite::SetDoNotInlineCall() { |
+ int value = Smi::cast(transition_info())->value(); |
+ set_transition_info(Smi::FromInt(DoNotInlineBit::update(value, true)), |
+ SKIP_WRITE_BARRIER); |
+} |
+ |
+ |
+bool AllocationSite::SitePointsToLiteral() { |
+ // If transition_info is a smi, then it represents an ElementsKind |
+ // for a constructed array. Otherwise, it must be a boilerplate |
+ // for an object or array literal. |
+ return transition_info()->IsJSArray() || transition_info()->IsJSObject(); |
+} |
+ |
+ |
// Heuristic: We only need to create allocation site info if the boilerplate |
// elements kind is the initial elements kind. |
AllocationSiteMode AllocationSite::GetMode( |
@@ -1787,6 +1837,39 @@ inline bool AllocationSite::CanTrack(InstanceType type) { |
} |
+AllocationSite::PretenureDecision AllocationSite::pretenure_decision() { |
+ int value = pretenure_data()->value(); |
+ return PretenureDecisionBits::decode(value); |
+} |
+ |
+ |
+void AllocationSite::set_pretenure_decision(PretenureDecision decision) { |
+ int value = pretenure_data()->value(); |
+ set_pretenure_data( |
+ Smi::FromInt(PretenureDecisionBits::update(value, decision)), |
+ SKIP_WRITE_BARRIER); |
+} |
+ |
+ |
+bool AllocationSite::deopt_dependent_code() { |
+ int value = pretenure_data()->value(); |
+ return DeoptDependentCodeBit::decode(value); |
+} |
+ |
+ |
+void AllocationSite::set_deopt_dependent_code(bool deopt) { |
+ int value = pretenure_data()->value(); |
+ set_pretenure_data(Smi::FromInt(DeoptDependentCodeBit::update(value, deopt)), |
+ SKIP_WRITE_BARRIER); |
+} |
+ |
+ |
+int AllocationSite::memento_found_count() { |
+ int value = pretenure_data()->value(); |
+ return MementoFoundCountBits::decode(value); |
+} |
+ |
+ |
inline void AllocationSite::set_memento_found_count(int count) { |
int value = pretenure_data()->value(); |
// Verify that we can count more mementos than we can possibly find in one |
@@ -1800,6 +1883,17 @@ inline void AllocationSite::set_memento_found_count(int count) { |
SKIP_WRITE_BARRIER); |
} |
+ |
+int AllocationSite::memento_create_count() { |
+ return pretenure_create_count()->value(); |
+} |
+ |
+ |
+void AllocationSite::set_memento_create_count(int count) { |
+ set_pretenure_create_count(Smi::FromInt(count), SKIP_WRITE_BARRIER); |
+} |
+ |
+ |
inline bool AllocationSite::IncrementMementoFoundCount() { |
if (IsZombie()) return false; |
@@ -1873,6 +1967,18 @@ inline bool AllocationSite::DigestPretenuringFeedback( |
} |
+bool AllocationMemento::IsValid() { |
+ return allocation_site()->IsAllocationSite() && |
+ !AllocationSite::cast(allocation_site())->IsZombie(); |
+} |
+ |
+ |
+AllocationSite* AllocationMemento::GetAllocationSite() { |
+ DCHECK(IsValid()); |
+ return AllocationSite::cast(allocation_site()); |
+} |
+ |
+ |
void JSObject::EnsureCanContainHeapObjectElements(Handle<JSObject> object) { |
JSObject::ValidateElements(object); |
ElementsKind elements_kind = object->map()->elements_kind(); |
@@ -2015,6 +2121,17 @@ ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset) |
ACCESSORS(PropertyCell, property_details_raw, Object, kDetailsOffset) |
ACCESSORS(PropertyCell, value, Object, kValueOffset) |
+ |
+PropertyDetails PropertyCell::property_details() { |
+ return PropertyDetails(Smi::cast(property_details_raw())); |
+} |
+ |
+ |
+void PropertyCell::set_property_details(PropertyDetails details) { |
+ set_property_details_raw(details.AsSmi()); |
+} |
+ |
+ |
Object* WeakCell::value() const { return READ_FIELD(this, kValueOffset); } |
@@ -2628,6 +2745,11 @@ Object** FixedArray::data_start() { |
} |
+Object** FixedArray::RawFieldOfElementAt(int index) { |
+ return HeapObject::RawField(this, OffsetOfElementAt(index)); |
+} |
+ |
+ |
bool DescriptorArray::IsEmpty() { |
DCHECK(length() >= kFirstIndex || |
this == GetHeap()->empty_descriptor_array()); |
@@ -2635,12 +2757,75 @@ bool DescriptorArray::IsEmpty() { |
} |
+int DescriptorArray::number_of_descriptors() { |
+ DCHECK(length() >= kFirstIndex || IsEmpty()); |
+ int len = length(); |
+ return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value(); |
+} |
+ |
+ |
+int DescriptorArray::number_of_descriptors_storage() { |
+ int len = length(); |
+ return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize; |
+} |
+ |
+ |
+int DescriptorArray::NumberOfSlackDescriptors() { |
+ return number_of_descriptors_storage() - number_of_descriptors(); |
+} |
+ |
+ |
void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) { |
WRITE_FIELD( |
this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors)); |
} |
+inline int DescriptorArray::number_of_entries() { |
+ return number_of_descriptors(); |
+} |
+ |
+ |
+bool DescriptorArray::HasEnumCache() { |
+ return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); |
+} |
+ |
+ |
+void DescriptorArray::CopyEnumCacheFrom(DescriptorArray* array) { |
+ set(kEnumCacheIndex, array->get(kEnumCacheIndex)); |
+} |
+ |
+ |
+FixedArray* DescriptorArray::GetEnumCache() { |
+ DCHECK(HasEnumCache()); |
+ FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); |
+ return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex)); |
+} |
+ |
+ |
+bool DescriptorArray::HasEnumIndicesCache() { |
+ if (IsEmpty()) return false; |
+ Object* object = get(kEnumCacheIndex); |
+ if (object->IsSmi()) return false; |
+ FixedArray* bridge = FixedArray::cast(object); |
+ return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi(); |
+} |
+ |
+ |
+FixedArray* DescriptorArray::GetEnumIndicesCache() { |
+ DCHECK(HasEnumIndicesCache()); |
+ FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); |
+ return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex)); |
+} |
+ |
+ |
+Object** DescriptorArray::GetEnumCacheSlot() { |
+ DCHECK(HasEnumCache()); |
+ return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), |
+ kEnumCacheOffset); |
+} |
+ |
+ |
// Perform a binary search in a fixed array. Low and high are entry indices. If |
// there are three entries in this array it should be called with low=0 and |
// high=2. |
@@ -2776,6 +2961,37 @@ PropertyDetails Map::GetLastDescriptorDetails() { |
} |
+int Map::LastAdded() { |
+ int number_of_own_descriptors = NumberOfOwnDescriptors(); |
+ DCHECK(number_of_own_descriptors > 0); |
+ return number_of_own_descriptors - 1; |
+} |
+ |
+ |
+int Map::NumberOfOwnDescriptors() { |
+ return NumberOfOwnDescriptorsBits::decode(bit_field3()); |
+} |
+ |
+ |
+void Map::SetNumberOfOwnDescriptors(int number) { |
+ DCHECK(number <= instance_descriptors()->number_of_descriptors()); |
+ set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number)); |
+} |
+ |
+ |
+int Map::EnumLength() { return EnumLengthBits::decode(bit_field3()); } |
+ |
+ |
+void Map::SetEnumLength(int length) { |
+ if (length != kInvalidEnumCacheSentinel) { |
+ DCHECK(length >= 0); |
+ DCHECK(length == 0 || instance_descriptors()->HasEnumCache()); |
+ DCHECK(length <= NumberOfOwnDescriptors()); |
+ } |
+ set_bit_field3(EnumLengthBits::update(bit_field3(), length)); |
+} |
+ |
+ |
FixedArrayBase* Map::GetInitialElements() { |
if (has_fast_smi_or_object_elements() || |
has_fast_double_elements()) { |
@@ -2983,6 +3199,47 @@ DescriptorArray::WhitenessWitness::~WhitenessWitness() { |
} |
+PropertyType DescriptorArray::Entry::type() { return descs_->GetType(index_); } |
+ |
+ |
+Object* DescriptorArray::Entry::GetCallbackObject() { |
+ return descs_->GetValue(index_); |
+} |
+ |
+ |
+int HashTableBase::NumberOfElements() { |
+ return Smi::cast(get(kNumberOfElementsIndex))->value(); |
+} |
+ |
+ |
+int HashTableBase::NumberOfDeletedElements() { |
+ return Smi::cast(get(kNumberOfDeletedElementsIndex))->value(); |
+} |
+ |
+ |
+int HashTableBase::Capacity() { |
+ return Smi::cast(get(kCapacityIndex))->value(); |
+} |
+ |
+ |
+void HashTableBase::ElementAdded() { |
+ SetNumberOfElements(NumberOfElements() + 1); |
+} |
+ |
+ |
+void HashTableBase::ElementRemoved() { |
+ SetNumberOfElements(NumberOfElements() - 1); |
+ SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); |
+} |
+ |
+ |
+void HashTableBase::ElementsRemoved(int n) { |
+ SetNumberOfElements(NumberOfElements() - n); |
+ SetNumberOfDeletedElements(NumberOfDeletedElements() + n); |
+} |
+ |
+ |
+// static |
int HashTableBase::ComputeCapacity(int at_least_space_for) { |
const int kMinCapacity = 4; |
int capacity = base::bits::RoundUpToPowerOfTwo32(at_least_space_for * 2); |
@@ -2990,6 +3247,21 @@ int HashTableBase::ComputeCapacity(int at_least_space_for) { |
} |
+bool HashTableBase::IsKey(Object* k) { |
+ return !k->IsTheHole() && !k->IsUndefined(); |
+} |
+ |
+ |
+void HashTableBase::SetNumberOfElements(int nof) { |
+ set(kNumberOfElementsIndex, Smi::FromInt(nof)); |
+} |
+ |
+ |
+void HashTableBase::SetNumberOfDeletedElements(int nod) { |
+ set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod)); |
+} |
+ |
+ |
template <typename Derived, typename Shape, typename Key> |
int HashTable<Derived, Shape, Key>::FindEntry(Key key) { |
return FindEntry(GetIsolate(), key); |
@@ -3163,6 +3435,116 @@ FixedTypedArray<Traits>::cast(const Object* object) { |
} |
+#define DEFINE_DEOPT_ELEMENT_ACCESSORS(name, type) \ |
+ type* DeoptimizationInputData::name() { \ |
+ return type::cast(get(k##name##Index)); \ |
+ } \ |
+ void DeoptimizationInputData::Set##name(type* value) { \ |
+ set(k##name##Index, value); \ |
+ } |
+ |
+DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray) |
+DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi) |
+DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray) |
+DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrAstId, Smi) |
+DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi) |
+DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi) |
+DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object) |
+DEFINE_DEOPT_ELEMENT_ACCESSORS(WeakCellCache, Object) |
+ |
+#undef DEFINE_DEOPT_ELEMENT_ACCESSORS |
+ |
+ |
+#define DEFINE_DEOPT_ENTRY_ACCESSORS(name, type) \ |
+ type* DeoptimizationInputData::name(int i) { \ |
+ return type::cast(get(IndexForEntry(i) + k##name##Offset)); \ |
+ } \ |
+ void DeoptimizationInputData::Set##name(int i, type* value) { \ |
+ set(IndexForEntry(i) + k##name##Offset, value); \ |
+ } |
+ |
+DEFINE_DEOPT_ENTRY_ACCESSORS(AstIdRaw, Smi) |
+DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi) |
+DEFINE_DEOPT_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi) |
+DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi) |
+ |
+#undef DEFINE_DEOPT_ENTRY_ACCESSORS |
+ |
+ |
+BailoutId DeoptimizationInputData::AstId(int i) { |
+ return BailoutId(AstIdRaw(i)->value()); |
+} |
+ |
+ |
+void DeoptimizationInputData::SetAstId(int i, BailoutId value) { |
+ SetAstIdRaw(i, Smi::FromInt(value.ToInt())); |
+} |
+ |
+ |
+int DeoptimizationInputData::DeoptCount() { |
+ return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize; |
+} |
+ |
+ |
+int DeoptimizationOutputData::DeoptPoints() { return length() / 2; } |
+ |
+ |
+BailoutId DeoptimizationOutputData::AstId(int index) { |
+ return BailoutId(Smi::cast(get(index * 2))->value()); |
+} |
+ |
+ |
+void DeoptimizationOutputData::SetAstId(int index, BailoutId id) { |
+ set(index * 2, Smi::FromInt(id.ToInt())); |
+} |
+ |
+ |
+Smi* DeoptimizationOutputData::PcAndState(int index) { |
+ return Smi::cast(get(1 + index * 2)); |
+} |
+ |
+ |
+void DeoptimizationOutputData::SetPcAndState(int index, Smi* offset) { |
+ set(1 + index * 2, offset); |
+} |
+ |
+ |
+void HandlerTable::SetRangeStart(int index, int value) { |
+ set(index * kRangeEntrySize + kRangeStartIndex, Smi::FromInt(value)); |
+} |
+ |
+ |
+void HandlerTable::SetRangeEnd(int index, int value) { |
+ set(index * kRangeEntrySize + kRangeEndIndex, Smi::FromInt(value)); |
+} |
+ |
+ |
+void HandlerTable::SetRangeHandler(int index, int offset, |
+ CatchPrediction prediction) { |
+ int value = HandlerOffsetField::encode(offset) | |
+ HandlerPredictionField::encode(prediction); |
+ set(index * kRangeEntrySize + kRangeHandlerIndex, Smi::FromInt(value)); |
+} |
+ |
+ |
+void HandlerTable::SetRangeDepth(int index, int value) { |
+ set(index * kRangeEntrySize + kRangeDepthIndex, Smi::FromInt(value)); |
+} |
+ |
+ |
+void HandlerTable::SetReturnOffset(int index, int value) { |
+ set(index * kReturnEntrySize + kReturnOffsetIndex, Smi::FromInt(value)); |
+} |
+ |
+ |
+void HandlerTable::SetReturnHandler(int index, int offset, |
+ CatchPrediction prediction) { |
+ int value = HandlerOffsetField::encode(offset) | |
+ HandlerPredictionField::encode(prediction); |
+ set(index * kReturnEntrySize + kReturnHandlerIndex, Smi::FromInt(value)); |
+} |
+ |
+ |
#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) |
STRUCT_LIST(MAKE_STRUCT_CAST) |
#undef MAKE_STRUCT_CAST |
@@ -3194,6 +3576,9 @@ SMI_ACCESSORS(String, length, kLengthOffset) |
SYNCHRONIZED_SMI_ACCESSORS(String, length, kLengthOffset) |
+int FreeSpace::Size() { return size(); } |
+ |
+ |
FreeSpace* FreeSpace::next() { |
DCHECK(map() == GetHeap()->raw_unchecked_free_space_map() || |
(!GetHeap()->deserialization_complete() && map() == NULL)); |
@@ -3685,6 +4070,9 @@ void StringCharacterStream::VisitTwoByteString( |
} |
+int ByteArray::Size() { return RoundUp(length() + kHeaderSize, kPointerSize); } |
+ |
+ |
byte ByteArray::get(int index) { |
DCHECK(index >= 0 && index < this->length()); |
return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); |
@@ -3709,6 +4097,9 @@ ByteArray* ByteArray::FromDataStartAddress(Address address) { |
} |
+int ByteArray::ByteArraySize() { return SizeFor(this->length()); } |
+ |
+ |
Address ByteArray::GetDataStartAddress() { |
return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize; |
} |
@@ -3743,6 +4134,9 @@ Address BytecodeArray::GetFirstBytecodeAddress() { |
} |
+int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); } |
+ |
+ |
ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset) |
@@ -4158,6 +4552,51 @@ bool Map::function_with_prototype() { |
} |
+void Map::set_is_hidden_prototype() { |
+ set_bit_field(bit_field() | (1 << kIsHiddenPrototype)); |
+} |
+ |
+ |
+bool Map::is_hidden_prototype() { |
+ return ((1 << kIsHiddenPrototype) & bit_field()) != 0; |
+} |
+ |
+ |
+void Map::set_has_indexed_interceptor() { |
+ set_bit_field(bit_field() | (1 << kHasIndexedInterceptor)); |
+} |
+ |
+ |
+bool Map::has_indexed_interceptor() { |
+ return ((1 << kHasIndexedInterceptor) & bit_field()) != 0; |
+} |
+ |
+ |
+void Map::set_is_undetectable() { |
+ set_bit_field(bit_field() | (1 << kIsUndetectable)); |
+} |
+ |
+ |
+bool Map::is_undetectable() { |
+ return ((1 << kIsUndetectable) & bit_field()) != 0; |
+} |
+ |
+ |
+void Map::set_is_observed() { set_bit_field(bit_field() | (1 << kIsObserved)); } |
+ |
+bool Map::is_observed() { return ((1 << kIsObserved) & bit_field()) != 0; } |
+ |
+ |
+void Map::set_has_named_interceptor() { |
+ set_bit_field(bit_field() | (1 << kHasNamedInterceptor)); |
+} |
+ |
+ |
+bool Map::has_named_interceptor() { |
+ return ((1 << kHasNamedInterceptor) & bit_field()) != 0; |
+} |
+ |
+ |
void Map::set_is_access_check_needed(bool access_check_needed) { |
if (access_check_needed) { |
set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded)); |
@@ -4194,6 +4633,50 @@ bool Map::is_prototype_map() const { |
} |
+void Map::set_elements_kind(ElementsKind elements_kind) { |
+ DCHECK(static_cast<int>(elements_kind) < kElementsKindCount); |
+ DCHECK(kElementsKindCount <= (1 << Map::ElementsKindBits::kSize)); |
+ set_bit_field2(Map::ElementsKindBits::update(bit_field2(), elements_kind)); |
+ DCHECK(this->elements_kind() == elements_kind); |
+} |
+ |
+ |
+ElementsKind Map::elements_kind() { |
+ return Map::ElementsKindBits::decode(bit_field2()); |
+} |
+ |
+ |
+bool Map::has_fast_smi_elements() { |
+ return IsFastSmiElementsKind(elements_kind()); |
+} |
+ |
+bool Map::has_fast_object_elements() { |
+ return IsFastObjectElementsKind(elements_kind()); |
+} |
+ |
+bool Map::has_fast_smi_or_object_elements() { |
+ return IsFastSmiOrObjectElementsKind(elements_kind()); |
+} |
+ |
+bool Map::has_fast_double_elements() { |
+ return IsFastDoubleElementsKind(elements_kind()); |
+} |
+ |
+bool Map::has_fast_elements() { return IsFastElementsKind(elements_kind()); } |
+ |
+bool Map::has_sloppy_arguments_elements() { |
+ return IsSloppyArgumentsElements(elements_kind()); |
+} |
+ |
+bool Map::has_fixed_typed_array_elements() { |
+ return IsFixedTypedArrayElementsKind(elements_kind()); |
+} |
+ |
+bool Map::has_dictionary_elements() { |
+ return IsDictionaryElementsKind(elements_kind()); |
+} |
+ |
+ |
void Map::set_dictionary_map(bool value) { |
uint32_t new_bit_field3 = DictionaryMap::update(bit_field3(), value); |
new_bit_field3 = IsUnstable::update(new_bit_field3, value); |
@@ -4308,6 +4791,39 @@ void Map::NotifyLeafMapLayoutChange() { |
} |
+bool Map::CanTransition() { |
+ // Only JSObject and subtypes have map transitions and back pointers. |
+ STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE); |
+ return instance_type() >= FIRST_JS_OBJECT_TYPE; |
+} |
+ |
+ |
+bool Map::IsPrimitiveMap() { |
+ STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); |
+ return instance_type() <= LAST_PRIMITIVE_TYPE; |
+} |
+bool Map::IsJSObjectMap() { |
+ STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
+ return instance_type() >= FIRST_JS_OBJECT_TYPE; |
+} |
+bool Map::IsJSArrayMap() { return instance_type() == JS_ARRAY_TYPE; } |
+bool Map::IsStringMap() { return instance_type() < FIRST_NONSTRING_TYPE; } |
+bool Map::IsJSProxyMap() { |
+ InstanceType type = instance_type(); |
+ return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE; |
+} |
+bool Map::IsJSGlobalProxyMap() { |
+ return instance_type() == JS_GLOBAL_PROXY_TYPE; |
+} |
+bool Map::IsJSGlobalObjectMap() { |
+ return instance_type() == JS_GLOBAL_OBJECT_TYPE; |
+} |
+bool Map::IsGlobalObjectMap() { |
+ const InstanceType type = instance_type(); |
+ return type == JS_GLOBAL_OBJECT_TYPE || type == JS_BUILTINS_OBJECT_TYPE; |
+} |
+ |
+ |
bool Map::CanOmitMapChecks() { |
return is_stable() && FLAG_omit_map_checks_for_leaf_maps; |
} |
@@ -4647,8 +5163,25 @@ bool Code::is_keyed_stub() { |
} |
-bool Code::is_debug_stub() { |
- return ic_state() == DEBUG_STUB; |
+bool Code::is_debug_stub() { return ic_state() == DEBUG_STUB; } |
+bool Code::is_handler() { return kind() == HANDLER; } |
+bool Code::is_load_stub() { return kind() == LOAD_IC; } |
+bool Code::is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; } |
+bool Code::is_store_stub() { return kind() == STORE_IC; } |
+bool Code::is_keyed_store_stub() { return kind() == KEYED_STORE_IC; } |
+bool Code::is_call_stub() { return kind() == CALL_IC; } |
+bool Code::is_binary_op_stub() { return kind() == BINARY_OP_IC; } |
+bool Code::is_compare_ic_stub() { return kind() == COMPARE_IC; } |
+bool Code::is_compare_nil_ic_stub() { return kind() == COMPARE_NIL_IC; } |
+bool Code::is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; } |
+bool Code::is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; } |
+ |
+ |
+bool Code::embeds_maps_weakly() { |
+ Kind k = kind(); |
+ return (k == LOAD_IC || k == STORE_IC || k == KEYED_LOAD_IC || |
+ k == KEYED_STORE_IC || k == COMPARE_NIL_IC) && |
+ ic_state() == MONOMORPHIC; |
} |
@@ -4745,6 +5278,18 @@ Object* Code::GetObjectFromEntryAddress(Address location_of_address) { |
} |
+bool Code::CanContainWeakObjects() { |
+ // is_turbofanned() implies !can_have_weak_objects(). |
+ DCHECK(!is_optimized_code() || !is_turbofanned() || !can_have_weak_objects()); |
+ return is_optimized_code() && can_have_weak_objects(); |
+} |
+ |
+ |
+bool Code::IsWeakObject(Object* object) { |
+ return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object)); |
+} |
+ |
+ |
bool Code::IsWeakObjectInOptimizedCode(Object* object) { |
if (object->IsMap()) { |
return Map::cast(object)->CanTransition() && |
@@ -5530,6 +6075,12 @@ void SharedFunctionInfo::TryReenableOptimization() { |
} |
+void SharedFunctionInfo::set_disable_optimization_reason(BailoutReason reason) { |
+ set_opt_count_and_bailout_reason(DisabledOptimizationReasonBits::update( |
+ opt_count_and_bailout_reason(), reason)); |
+} |
+ |
+ |
bool SharedFunctionInfo::IsSubjectToDebugging() { |
Object* script_obj = script(); |
if (script_obj->IsUndefined()) return false; |
@@ -5960,6 +6511,17 @@ bool Code::contains(byte* inner_pointer) { |
} |
+int Code::ExecutableSize() { |
+ // Check that the assumptions about the layout of the code object holds. |
+ DCHECK_EQ(static_cast<int>(instruction_start() - address()), |
+ Code::kHeaderSize); |
+ return instruction_size() + Code::kHeaderSize; |
+} |
+ |
+ |
+int Code::CodeSize() { return SizeFor(body_size()); } |
+ |
+ |
ACCESSORS(JSArray, length, Object, kLengthOffset) |
@@ -6414,6 +6976,10 @@ uint32_t StringHasher::HashSequentialString(const schar* chars, |
} |
+IteratingStringHasher::IteratingStringHasher(int len, uint32_t seed) |
+ : StringHasher(len, seed) {} |
+ |
+ |
uint32_t IteratingStringHasher::Hash(String* string, uint32_t seed) { |
IteratingStringHasher hasher(string->length(), seed); |
// Nothing to do. |
@@ -6647,6 +7213,51 @@ bool AccessorInfo::IsCompatibleReceiver(Object* receiver) { |
} |
+bool AccessorInfo::HasExpectedReceiverType() { |
+ return expected_receiver_type()->IsFunctionTemplateInfo(); |
+} |
+ |
+ |
+Object* AccessorPair::get(AccessorComponent component) { |
+ return component == ACCESSOR_GETTER ? getter() : setter(); |
+} |
+ |
+ |
+void AccessorPair::set(AccessorComponent component, Object* value) { |
+ if (component == ACCESSOR_GETTER) { |
+ set_getter(value); |
+ } else { |
+ set_setter(value); |
+ } |
+} |
+ |
+ |
+void AccessorPair::SetComponents(Object* getter, Object* setter) { |
+ if (!getter->IsNull()) set_getter(getter); |
+ if (!setter->IsNull()) set_setter(setter); |
+} |
+ |
+ |
+bool AccessorPair::Equals(AccessorPair* pair) { |
+ return (this == pair) || pair->Equals(getter(), setter()); |
+} |
+ |
+ |
+bool AccessorPair::Equals(Object* getter_value, Object* setter_value) { |
+ return (getter() == getter_value) && (setter() == setter_value); |
+} |
+ |
+ |
+bool AccessorPair::ContainsAccessor() { |
+ return IsJSAccessor(getter()) || IsJSAccessor(setter()); |
+} |
+ |
+ |
+bool AccessorPair::IsJSAccessor(Object* obj) { |
+ return obj->IsSpecFunction() || obj->IsUndefined(); |
+} |
+ |
+ |
template<typename Derived, typename Shape, typename Key> |
void Dictionary<Derived, Shape, Key>::SetEntry(int entry, |
Handle<Object> key, |
@@ -6820,6 +7431,11 @@ Handle<ObjectHashTable> ObjectHashTable::Shrink( |
} |
+Object* OrderedHashMap::ValueAt(int entry) { |
+ return get(EntryToIndex(entry) + kValueOffset); |
+} |
+ |
+ |
template <int entrysize> |
bool WeakHashTableShape<entrysize>::IsMatch(Handle<Object> key, Object* other) { |
if (other->IsWeakCell()) other = WeakCell::cast(other)->value(); |
@@ -6854,6 +7470,30 @@ Handle<Object> WeakHashTableShape<entrysize>::AsHandle(Isolate* isolate, |
} |
+bool ScopeInfo::IsAsmModule() { return AsmModuleField::decode(Flags()); } |
+ |
+ |
+bool ScopeInfo::IsAsmFunction() { return AsmFunctionField::decode(Flags()); } |
+ |
+ |
+bool ScopeInfo::HasSimpleParameters() { |
+ return HasSimpleParametersField::decode(Flags()); |
+} |
+ |
+ |
+#define SCOPE_INFO_FIELD_ACCESSORS(name) \ |
+ void ScopeInfo::Set##name(int value) { set(k##name, Smi::FromInt(value)); } \ |
+ int ScopeInfo::name() { \ |
+ if (length() > 0) { \ |
+ return Smi::cast(get(k##name))->value(); \ |
+ } else { \ |
+ return 0; \ |
+ } \ |
+ } |
+FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(SCOPE_INFO_FIELD_ACCESSORS) |
+#undef SCOPE_INFO_FIELD_ACCESSORS |
+ |
+ |
void Map::ClearCodeCache(Heap* heap) { |
// No write barrier is needed since empty_fixed_array is not in new space. |
// Please note this function is used during marking: |
@@ -7024,11 +7664,24 @@ Relocatable::~Relocatable() { |
} |
+// static |
int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) { |
return map->instance_size(); |
} |
+// static |
+int FixedArray::BodyDescriptor::SizeOf(Map* map, HeapObject* object) { |
+ return SizeFor(reinterpret_cast<FixedArray*>(object)->synchronized_length()); |
+} |
+ |
+ |
+// static |
+int StructBodyDescriptor::SizeOf(Map* map, HeapObject* object) { |
+ return map->instance_size(); |
+} |
+ |
+ |
void Foreign::ForeignIterateBody(ObjectVisitor* v) { |
v->VisitExternalReference( |
reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset))); |
@@ -7161,6 +7814,12 @@ Object* JSMapIterator::CurrentValue() { |
} |
+String::SubStringRange::SubStringRange(String* string, int first, int length) |
+ : string_(string), |
+ first_(first), |
+ length_(length == -1 ? string->length() : length) {} |
+ |
+ |
class String::SubStringRange::iterator final { |
public: |
typedef std::forward_iterator_tag iterator_category; |