[cleanup] Move some stuff out of objects-inl.h

HeapObject::SizeFromMap() was too large to get inlined anyway.
HeapObject::IsFoo() predicates should be implemented in foo-inl.h,
because that's what they depend on.
This patch also fixes up includes: dropping unnecessary ones from
object-inl.h, and adding them in other places that previously
relied on getting them transitively.

Bug: v8:8562
Change-Id: Id062bed67257d9dc1899f2d71f44cf69a1368c83
Reviewed-on: https://chromium-review.googlesource.com/c/1450778
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59478}
This commit is contained in:
Jakob Kummerow 2019-02-07 12:27:25 -08:00 committed by Commit Bot
parent 8c684d5666
commit 455200e009
40 changed files with 300 additions and 328 deletions

View File

@ -9,6 +9,7 @@
#include "src/counters.h"
#include "src/deoptimizer.h"
#include "src/execution.h"
#include "src/field-index-inl.h"
#include "src/frames-inl.h"
#include "src/heap/factory.h"
#include "src/isolate-inl.h"

View File

@ -17,6 +17,17 @@
namespace v8 {
namespace internal {
void Object::VerifyApiCallResultType() {
#if DEBUG
if (IsSmi()) return;
DCHECK(IsHeapObject());
if (!(IsString() || IsSymbol() || IsJSReceiver() || IsHeapNumber() ||
IsBigInt() || IsUndefined() || IsTrue() || IsFalse() || IsNull())) {
FATAL("API call returned invalid object");
}
#endif // DEBUG
}
CustomArgumentsBase::CustomArgumentsBase(Isolate* isolate)
: Relocatable(isolate) {}

View File

@ -6,6 +6,7 @@
#include "src/builtins/builtins-utils-inl.h"
#include "src/builtins/builtins.h"
#include "src/counters.h"
#include "src/isolate-inl.h"
#include "src/messages.h"
#include "src/objects-inl.h"
#include "src/objects/api-callbacks.h"

View File

@ -4,6 +4,7 @@
#include "src/feedback-vector.h"
#include "src/feedback-vector-inl.h"
#include "src/ic/handler-configuration-inl.h"
#include "src/ic/ic-inl.h"
#include "src/objects.h"
#include "src/objects/data-handler-inl.h"

View File

@ -12,16 +12,15 @@
namespace v8 {
namespace internal {
inline FieldIndex FieldIndex::ForInObjectOffset(int offset, Encoding encoding) {
FieldIndex FieldIndex::ForInObjectOffset(int offset, Encoding encoding) {
DCHECK_IMPLIES(encoding == kWord32, IsAligned(offset, kInt32Size));
DCHECK_IMPLIES(encoding == kTagged, IsAligned(offset, kTaggedSize));
DCHECK_IMPLIES(encoding == kDouble, IsAligned(offset, kDoubleSize));
return FieldIndex(true, offset, encoding, 0, 0);
}
inline FieldIndex FieldIndex::ForPropertyIndex(const Map map,
int property_index,
Representation representation) {
FieldIndex FieldIndex::ForPropertyIndex(const Map map, int property_index,
Representation representation) {
DCHECK(map->instance_type() >= FIRST_NONSTRING_TYPE);
int inobject_properties = map->GetInObjectProperties();
bool is_inobject = property_index < inobject_properties;
@ -43,7 +42,7 @@ inline FieldIndex FieldIndex::ForPropertyIndex(const Map map,
// Returns the index format accepted by the HLoadFieldByIndex instruction.
// (In-object: zero-based from (object start + JSObject::kHeaderSize),
// out-of-object: zero-based from FixedArray::kHeaderSize.)
inline int FieldIndex::GetLoadByFieldIndex() const {
int FieldIndex::GetLoadByFieldIndex() const {
// For efficiency, the LoadByFieldIndex instruction takes an index that is
// optimized for quick access. If the property is inline, the index is
// positive. If it's out-of-line, the encoded index is -raw_index - 1 to
@ -61,8 +60,7 @@ inline int FieldIndex::GetLoadByFieldIndex() const {
return is_double() ? (result | 1) : result;
}
inline FieldIndex FieldIndex::ForDescriptor(const Map map,
int descriptor_index) {
FieldIndex FieldIndex::ForDescriptor(const Map map, int descriptor_index) {
PropertyDetails details =
map->instance_descriptors()->GetDetails(descriptor_index);
int field_index = details.field_index();

View File

@ -23,13 +23,13 @@ class FieldIndex final {
FieldIndex() : bit_field_(0) {}
static FieldIndex ForPropertyIndex(
static inline FieldIndex ForPropertyIndex(
const Map map, int index,
Representation representation = Representation::Tagged());
static FieldIndex ForInObjectOffset(int offset, Encoding encoding);
static FieldIndex ForDescriptor(const Map map, int descriptor_index);
static inline FieldIndex ForInObjectOffset(int offset, Encoding encoding);
static inline FieldIndex ForDescriptor(const Map map, int descriptor_index);
int GetLoadByFieldIndex() const;
inline int GetLoadByFieldIndex() const;
bool is_inobject() const {
return IsInObjectBits::decode(bit_field_);

View File

@ -19,8 +19,11 @@
#include "src/heap/objects-visiting.h"
#include "src/heap/worklist.h"
#include "src/isolate.h"
#include "src/objects/data-handler-inl.h"
#include "src/objects/embedder-data-array-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/slots-inl.h"
#include "src/transitions-inl.h"
#include "src/utils-inl.h"
#include "src/utils.h"
#include "src/v8.h"

View File

@ -10,6 +10,7 @@
// Clients of this interface shouldn't depend on lots of heap internals.
// Do not include anything from src/heap here!
#include "src/handles-inl.h"
#include "src/isolate-inl.h"
#include "src/objects-inl.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/oddball.h"

View File

@ -15,6 +15,7 @@
#include "src/conversions.h"
#include "src/counters.h"
#include "src/heap/mark-compact-inl.h"
#include "src/ic/handler-configuration-inl.h"
#include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h"
#include "src/log.h"
@ -41,6 +42,7 @@
#include "src/objects/scope-info.h"
#include "src/objects/stack-frame-info-inl.h"
#include "src/objects/struct-inl.h"
#include "src/transitions-inl.h"
#include "src/unicode-cache.h"
#include "src/unicode-inl.h"

View File

@ -3579,6 +3579,12 @@ void Heap::Verify() {
VerifyPointersVisitor visitor(this);
IterateRoots(&visitor, VISIT_ONLY_STRONG);
if (!isolate()->context().is_null() &&
!isolate()->normalized_map_cache()->IsUndefined(isolate())) {
NormalizedMapCache::cast(*isolate()->normalized_map_cache())
->NormalizedMapCacheVerify(isolate());
}
VerifySmisVisitor smis_visitor;
IterateSmiRoots(&smis_visitor);

View File

@ -17,9 +17,12 @@
#include "src/heap/objects-visiting-inl.h"
#include "src/heap/objects-visiting.h"
#include "src/heap/sweeper.h"
#include "src/objects/data-handler-inl.h"
#include "src/objects/embedder-data-array-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/slots-inl.h"
#include "src/tracing/trace-event.h"
#include "src/transitions-inl.h"
#include "src/v8.h"
#include "src/visitors.h"
#include "src/vm-state-inl.h"

View File

@ -27,6 +27,7 @@
#include "src/heap/sweeper.h"
#include "src/heap/worklist.h"
#include "src/ic/stub-cache.h"
#include "src/objects/embedder-data-array-inl.h"
#include "src/objects/foreign.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-objects-inl.h"

View File

@ -14,6 +14,9 @@
#include "src/heap/scavenger-inl.h"
#include "src/heap/sweeper.h"
#include "src/objects-body-descriptors-inl.h"
#include "src/objects/data-handler-inl.h"
#include "src/objects/embedder-data-array-inl.h"
#include "src/transitions-inl.h"
#include "src/utils-inl.h"
namespace v8 {

View File

@ -10,6 +10,7 @@
#include "src/heap-symbols.h"
#include "src/heap/factory.h"
#include "src/heap/heap.h"
#include "src/ic/handler-configuration.h"
#include "src/interpreter/interpreter.h"
#include "src/isolate.h"
#include "src/layout-descriptor.h"

View File

@ -6,6 +6,7 @@
#include "src/api-arguments-inl.h"
#include "src/elements-inl.h"
#include "src/field-index-inl.h"
#include "src/handles-inl.h"
#include "src/heap/factory.h"
#include "src/identity-map.h"
@ -14,6 +15,7 @@
#include "src/objects/api-callbacks.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/module-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
#include "src/property-descriptor.h"
#include "src/prototype.h"

View File

@ -9,7 +9,7 @@
#include "src/handles-inl.h"
#include "src/objects-inl.h"
#include "src/objects/descriptor-array.h"
#include "src/objects/descriptor-array-inl.h"
#include "src/objects/smi.h"
// Has to be the last include (doesn't have include guards):

View File

@ -8,6 +8,7 @@
#include "src/feedback-vector.h"
#include "src/objects-body-descriptors.h"
#include "src/objects/cell.h"
#include "src/objects/data-handler.h"
#include "src/objects/foreign-inl.h"
#include "src/objects/hash-table.h"
#include "src/objects/js-collection.h"

View File

@ -12,6 +12,7 @@
#include "src/disassembler.h"
#include "src/elements.h"
#include "src/field-type.h"
#include "src/ic/handler-configuration-inl.h"
#include "src/layout-descriptor.h"
#include "src/objects-inl.h"
#include "src/objects/arguments-inl.h"
@ -59,7 +60,7 @@
#include "src/objects/struct-inl.h"
#include "src/ostreams.h"
#include "src/regexp/jsregexp.h"
#include "src/transitions.h"
#include "src/transitions-inl.h"
#include "src/wasm/wasm-objects-inl.h"
namespace v8 {

View File

@ -17,30 +17,18 @@
#include "src/base/bits.h"
#include "src/base/tsan.h"
#include "src/builtins/builtins.h"
#include "src/contexts-inl.h"
#include "src/conversions-inl.h"
#include "src/feedback-vector-inl.h"
#include "src/field-index-inl.h"
#include "src/conversions.h"
#include "src/double.h"
#include "src/handles-inl.h"
#include "src/heap/factory.h"
#include "src/heap/heap-inl.h" // crbug.com/v8/8499
#include "src/isolate-inl.h"
#include "src/keys.h"
#include "src/layout-descriptor-inl.h"
#include "src/lookup-cache-inl.h"
#include "src/lookup-inl.h"
#include "src/maybe-handles-inl.h"
#include "src/objects/bigint.h"
#include "src/objects/descriptor-array-inl.h"
#include "src/objects/embedder-data-array-inl.h"
#include "src/objects/free-space-inl.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/heap-object.h" // TODO(jkummerow): See below [1].
#include "src/objects/heap-object.h"
#include "src/objects/js-proxy-inl.h"
#include "src/objects/literal-objects.h"
#include "src/objects/maybe-object-inl.h"
#include "src/objects/oddball-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
#include "src/objects/oddball.h"
#include "src/objects/regexp-match-info.h"
#include "src/objects/scope-info.h"
#include "src/objects/slots-inl.h"
@ -49,18 +37,8 @@
#include "src/objects/templates.h"
#include "src/property-details.h"
#include "src/property.h"
#include "src/prototype-inl.h"
#include "src/roots-inl.h"
#include "src/transitions-inl.h"
#include "src/v8memory.h"
// [1] This file currently contains the definitions of many
// HeapObject::IsFoo() predicates, which in turn require #including
// many other -inl.h files. Find a way to avoid this. Idea:
// Since e.g. HeapObject::IsSeqString requires things from string-inl.h,
// and presumably is mostly used from places that require/include string-inl.h
// anyway, maybe that's where it should be defined?
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@ -84,11 +62,6 @@ int PropertyDetails::field_width_in_words() const {
return representation().IsDouble() ? kDoubleSize / kTaggedSize : 1;
}
bool HeapObject::IsUncompiledData() const {
return IsUncompiledDataWithoutPreparseData() ||
IsUncompiledDataWithPreparseData();
}
bool HeapObject::IsSloppyArgumentsElements() const {
return IsFixedArrayExact();
}
@ -330,11 +303,6 @@ bool HeapObject::IsSymbolWrapper() const {
return IsJSValue() && JSValue::cast(*this)->value()->IsSymbol();
}
bool HeapObject::IsBoolean() const {
return IsOddball() &&
((Oddball::cast(*this)->kind() & Oddball::kNotBooleanMask) == 0);
}
bool HeapObject::IsJSArrayBufferView() const {
return IsJSDataView() || IsJSTypedArray();
}
@ -343,10 +311,6 @@ bool HeapObject::IsStringSet() const { return IsHashTable(); }
bool HeapObject::IsObjectHashSet() const { return IsHashTable(); }
bool HeapObject::IsNormalizedMapCache() const {
return NormalizedMapCache::IsNormalizedMapCache(*this);
}
bool HeapObject::IsCompilationCacheTable() const { return IsHashTable(); }
bool HeapObject::IsMapCache() const { return IsHashTable(); }
@ -432,40 +396,8 @@ bool Object::IsMinusZero() const {
}
OBJECT_CONSTRUCTORS_IMPL(HeapObject, Object)
OBJECT_CONSTRUCTORS_IMPL(HashTableBase, FixedArray)
template <typename Derived, typename Shape>
HashTable<Derived, Shape>::HashTable(Address ptr) : HashTableBase(ptr) {
SLOW_DCHECK(IsHashTable());
}
template <typename Derived, typename Shape>
ObjectHashTableBase<Derived, Shape>::ObjectHashTableBase(Address ptr)
: HashTable<Derived, Shape>(ptr) {}
ObjectHashTable::ObjectHashTable(Address ptr)
: ObjectHashTableBase<ObjectHashTable, ObjectHashTableShape>(ptr) {
SLOW_DCHECK(IsObjectHashTable());
}
EphemeronHashTable::EphemeronHashTable(Address ptr)
: ObjectHashTableBase<EphemeronHashTable, EphemeronHashTableShape>(ptr) {
SLOW_DCHECK(IsEphemeronHashTable());
}
ObjectHashSet::ObjectHashSet(Address ptr)
: HashTable<ObjectHashSet, ObjectHashSetShape>(ptr) {
SLOW_DCHECK(IsObjectHashSet());
}
OBJECT_CONSTRUCTORS_IMPL(RegExpMatchInfo, FixedArray)
OBJECT_CONSTRUCTORS_IMPL(ScopeInfo, FixedArray)
NormalizedMapCache::NormalizedMapCache(Address ptr) : WeakFixedArray(ptr) {
// TODO(jkummerow): Introduce IsNormalizedMapCache() and use
// OBJECT_CONSTRUCTORS_IMPL macro?
}
OBJECT_CONSTRUCTORS_IMPL(BigIntBase, HeapObject)
OBJECT_CONSTRUCTORS_IMPL(BigInt, BigIntBase)
OBJECT_CONSTRUCTORS_IMPL(FreshlyAllocatedBigInt, BigIntBase)
@ -476,13 +408,8 @@ OBJECT_CONSTRUCTORS_IMPL(TemplateObjectDescription, Tuple2)
// Cast operations
CAST_ACCESSOR(BigInt)
CAST_ACCESSOR(ObjectBoilerplateDescription)
CAST_ACCESSOR(EphemeronHashTable)
CAST_ACCESSOR(HeapObject)
CAST_ACCESSOR(NormalizedMapCache)
CAST_ACCESSOR(Object)
CAST_ACCESSOR(ObjectHashSet)
CAST_ACCESSOR(ObjectHashTable)
CAST_ACCESSOR(RegExpMatchInfo)
CAST_ACCESSOR(ScopeInfo)
CAST_ACCESSOR(TemplateObjectDescription)
@ -492,23 +419,6 @@ bool Object::HasValidElements() {
return IsFixedArray() || IsFixedDoubleArray() || IsFixedTypedArrayBase();
}
bool Object::KeyEquals(Object second) {
Object first = *this;
if (second->IsNumber()) {
if (first->IsNumber()) return first->Number() == second->Number();
Object temp = first;
first = second;
second = temp;
}
if (first->IsNumber()) {
DCHECK_LE(0, first->Number());
uint32_t expected = static_cast<uint32_t>(first->Number());
uint32_t index;
return Name::cast(second)->AsArrayIndex(&index) && index == expected;
}
return Name::cast(first)->Equals(Name::cast(second));
}
bool Object::FilterKey(PropertyFilter filter) {
DCHECK(!IsPropertyCell());
if (IsSymbol()) {
@ -520,33 +430,6 @@ bool Object::FilterKey(PropertyFilter filter) {
return false;
}
Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object,
Representation representation) {
if (!representation.IsDouble()) return object;
auto result = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
if (object->IsUninitialized(isolate)) {
result->set_value_as_bits(kHoleNanInt64);
} else if (object->IsMutableHeapNumber()) {
// Ensure that all bits of the double value are preserved.
result->set_value_as_bits(
MutableHeapNumber::cast(*object)->value_as_bits());
} else {
result->set_value(object->Number());
}
return result;
}
Handle<Object> Object::WrapForRead(Isolate* isolate, Handle<Object> object,
Representation representation) {
DCHECK(!object->IsUninitialized(isolate));
if (!representation.IsDouble()) {
DCHECK(object->FitsRepresentation(representation));
return object;
}
return isolate->factory()->NewHeapNumber(
MutableHeapNumber::cast(*object)->value());
}
Representation Object::OptimalRepresentation() {
if (!FLAG_track_fields) return Representation::Tagged();
if (IsSmi()) {
@ -603,7 +486,7 @@ MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
Handle<Object> object,
const char* method_name) {
if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
return ToObject(isolate, object, isolate->native_context(), method_name);
return ToObjectImpl(isolate, object, method_name);
}
@ -878,17 +761,6 @@ HeapObject Object::GetHeapObject() const {
return HeapObject::cast(*this);
}
void Object::VerifyApiCallResultType() {
#if DEBUG
if (IsSmi()) return;
DCHECK(IsHeapObject());
if (!(IsString() || IsSymbol() || IsJSReceiver() || IsHeapNumber() ||
IsBigInt() || IsUndefined() || IsTrue() || IsFalse() || IsNull())) {
FATAL("API call returned invalid object");
}
#endif // DEBUG
}
int RegExpMatchInfo::NumberOfCaptureRegisters() {
DCHECK_GE(length(), kLastMatchOverhead);
Object obj = get(kNumberOfCapturesIndex);
@ -951,150 +823,10 @@ AllocationAlignment HeapObject::RequiredAlignment(Map map) {
return kWordAligned;
}
bool HeapObject::NeedsRehashing() const {
switch (map()->instance_type()) {
case DESCRIPTOR_ARRAY_TYPE:
return DescriptorArray::cast(*this)->number_of_descriptors() > 1;
case TRANSITION_ARRAY_TYPE:
return TransitionArray::cast(*this)->number_of_entries() > 1;
case ORDERED_HASH_MAP_TYPE:
return OrderedHashMap::cast(*this)->NumberOfElements() > 0;
case ORDERED_HASH_SET_TYPE:
return OrderedHashSet::cast(*this)->NumberOfElements() > 0;
case NAME_DICTIONARY_TYPE:
case GLOBAL_DICTIONARY_TYPE:
case NUMBER_DICTIONARY_TYPE:
case SIMPLE_NUMBER_DICTIONARY_TYPE:
case STRING_TABLE_TYPE:
case HASH_TABLE_TYPE:
case SMALL_ORDERED_HASH_MAP_TYPE:
case SMALL_ORDERED_HASH_SET_TYPE:
case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
return true;
default:
return false;
}
}
Address HeapObject::GetFieldAddress(int field_offset) const {
return FIELD_ADDR(this, field_offset);
}
ACCESSORS(EnumCache, keys, FixedArray, kKeysOffset)
ACCESSORS(EnumCache, indices, FixedArray, kIndicesOffset)
DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrBytecodeOffset, Smi)
DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
int HeapObject::SizeFromMap(Map map) const {
int instance_size = map->instance_size();
if (instance_size != kVariableSizeSentinel) return instance_size;
// Only inline the most frequent cases.
InstanceType instance_type = map->instance_type();
if (IsInRange(instance_type, FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE)) {
return FixedArray::SizeFor(
FixedArray::unchecked_cast(*this)->synchronized_length());
}
if (IsInRange(instance_type, FIRST_CONTEXT_TYPE, LAST_CONTEXT_TYPE)) {
// Native context has fixed size.
DCHECK_NE(instance_type, NATIVE_CONTEXT_TYPE);
return Context::SizeFor(Context::unchecked_cast(*this)->length());
}
if (instance_type == ONE_BYTE_STRING_TYPE ||
instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) {
// Strings may get concurrently truncated, hence we have to access its
// length synchronized.
return SeqOneByteString::SizeFor(
SeqOneByteString::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == BYTE_ARRAY_TYPE) {
return ByteArray::SizeFor(
ByteArray::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == BYTECODE_ARRAY_TYPE) {
return BytecodeArray::SizeFor(
BytecodeArray::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == FREE_SPACE_TYPE) {
return FreeSpace::unchecked_cast(*this)->relaxed_read_size();
}
if (instance_type == STRING_TYPE ||
instance_type == INTERNALIZED_STRING_TYPE) {
// Strings may get concurrently truncated, hence we have to access its
// length synchronized.
return SeqTwoByteString::SizeFor(
SeqTwoByteString::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
return FixedDoubleArray::SizeFor(
FixedDoubleArray::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == FEEDBACK_METADATA_TYPE) {
return FeedbackMetadata::SizeFor(
FeedbackMetadata::unchecked_cast(*this)->synchronized_slot_count());
}
if (instance_type == DESCRIPTOR_ARRAY_TYPE) {
return DescriptorArray::SizeFor(
DescriptorArray::unchecked_cast(*this)->number_of_all_descriptors());
}
if (IsInRange(instance_type, FIRST_WEAK_FIXED_ARRAY_TYPE,
LAST_WEAK_FIXED_ARRAY_TYPE)) {
return WeakFixedArray::SizeFor(
WeakFixedArray::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == WEAK_ARRAY_LIST_TYPE) {
return WeakArrayList::SizeForCapacity(
WeakArrayList::unchecked_cast(*this)->synchronized_capacity());
}
if (IsInRange(instance_type, FIRST_FIXED_TYPED_ARRAY_TYPE,
LAST_FIXED_TYPED_ARRAY_TYPE)) {
return FixedTypedArrayBase::unchecked_cast(*this)->TypedArraySize(
instance_type);
}
if (instance_type == SMALL_ORDERED_HASH_SET_TYPE) {
return SmallOrderedHashSet::SizeFor(
SmallOrderedHashSet::unchecked_cast(*this)->Capacity());
}
if (instance_type == SMALL_ORDERED_HASH_MAP_TYPE) {
return SmallOrderedHashMap::SizeFor(
SmallOrderedHashMap::unchecked_cast(*this)->Capacity());
}
if (instance_type == SMALL_ORDERED_NAME_DICTIONARY_TYPE) {
return SmallOrderedNameDictionary::SizeFor(
SmallOrderedNameDictionary::unchecked_cast(*this)->Capacity());
}
if (instance_type == PROPERTY_ARRAY_TYPE) {
return PropertyArray::SizeFor(
PropertyArray::cast(*this)->synchronized_length());
}
if (instance_type == FEEDBACK_VECTOR_TYPE) {
return FeedbackVector::SizeFor(
FeedbackVector::unchecked_cast(*this)->length());
}
if (instance_type == BIGINT_TYPE) {
return BigInt::SizeFor(BigInt::unchecked_cast(*this)->length());
}
if (instance_type == PREPARSE_DATA_TYPE) {
PreparseData data = PreparseData::unchecked_cast(*this);
return PreparseData::SizeFor(data->data_length(), data->children_length());
}
if (instance_type == CODE_TYPE) {
return Code::unchecked_cast(*this)->CodeSize();
}
DCHECK_EQ(instance_type, EMBEDDER_DATA_ARRAY_TYPE);
return EmbedderDataArray::SizeFor(
EmbedderDataArray::unchecked_cast(*this)->length());
}
ACCESSORS(TemplateObjectDescription, raw_strings, FixedArray, kRawStringsOffset)
ACCESSORS(TemplateObjectDescription, cooked_strings, FixedArray,
kCookedStringsOffset)
@ -1194,8 +926,6 @@ MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> receiver,
return GetProperty(&it);
}
// static
Object Object::GetSimpleHash(Object object) {
DisallowHeapAllocation no_gc;

View File

@ -55,8 +55,10 @@
#include "src/objects/code-inl.h"
#include "src/objects/compilation-cache-inl.h"
#include "src/objects/debug-objects-inl.h"
#include "src/objects/embedder-data-array-inl.h"
#include "src/objects/foreign.h"
#include "src/objects/frame-array-inl.h"
#include "src/objects/free-space-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-inl.h"
#ifdef V8_INTL_SUPPORT
@ -101,6 +103,7 @@
#include "src/string-builder-inl.h"
#include "src/string-search.h"
#include "src/string-stream.h"
#include "src/transitions-inl.h"
#include "src/unicode-decoder.h"
#include "src/unicode-inl.h"
#include "src/utils-inl.h"
@ -179,11 +182,38 @@ Handle<FieldType> Object::OptimalType(Isolate* isolate,
return FieldType::Any(isolate);
}
MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
Handle<Object> object,
Handle<Context> native_context,
const char* method_name) {
if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object,
Representation representation) {
if (!representation.IsDouble()) return object;
auto result = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
if (object->IsUninitialized(isolate)) {
result->set_value_as_bits(kHoleNanInt64);
} else if (object->IsMutableHeapNumber()) {
// Ensure that all bits of the double value are preserved.
result->set_value_as_bits(
MutableHeapNumber::cast(*object)->value_as_bits());
} else {
result->set_value(object->Number());
}
return result;
}
Handle<Object> Object::WrapForRead(Isolate* isolate, Handle<Object> object,
Representation representation) {
DCHECK(!object->IsUninitialized(isolate));
if (!representation.IsDouble()) {
DCHECK(object->FitsRepresentation(representation));
return object;
}
return isolate->factory()->NewHeapNumber(
MutableHeapNumber::cast(*object)->value());
}
MaybeHandle<JSReceiver> Object::ToObjectImpl(Isolate* isolate,
Handle<Object> object,
const char* method_name) {
DCHECK(!object->IsJSReceiver()); // Use ToObject() for fast path.
Handle<Context> native_context = isolate->native_context();
Handle<JSFunction> constructor;
if (object->IsSmi()) {
constructor = handle(native_context->number_function(), isolate);
@ -488,8 +518,7 @@ Handle<String> Object::NoSideEffectsToString(Isolate* isolate,
return isolate->factory()->NewStringFromAsciiChecked("[object Unknown]");
}
receiver = Object::ToObject(isolate, input, isolate->native_context())
.ToHandleChecked();
receiver = Object::ToObjectImpl(isolate, input).ToHandleChecked();
}
Handle<String> builtin_tag = handle(receiver->class_name(), isolate);
@ -2165,6 +2194,130 @@ bool HeapObject::IsValidSlot(Map map, int offset) {
*this, offset, 0);
}
int HeapObject::SizeFromMap(Map map) const {
int instance_size = map->instance_size();
if (instance_size != kVariableSizeSentinel) return instance_size;
// Only inline the most frequent cases.
InstanceType instance_type = map->instance_type();
if (IsInRange(instance_type, FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE)) {
return FixedArray::SizeFor(
FixedArray::unchecked_cast(*this)->synchronized_length());
}
if (IsInRange(instance_type, FIRST_CONTEXT_TYPE, LAST_CONTEXT_TYPE)) {
// Native context has fixed size.
DCHECK_NE(instance_type, NATIVE_CONTEXT_TYPE);
return Context::SizeFor(Context::unchecked_cast(*this)->length());
}
if (instance_type == ONE_BYTE_STRING_TYPE ||
instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) {
// Strings may get concurrently truncated, hence we have to access its
// length synchronized.
return SeqOneByteString::SizeFor(
SeqOneByteString::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == BYTE_ARRAY_TYPE) {
return ByteArray::SizeFor(
ByteArray::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == BYTECODE_ARRAY_TYPE) {
return BytecodeArray::SizeFor(
BytecodeArray::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == FREE_SPACE_TYPE) {
return FreeSpace::unchecked_cast(*this)->relaxed_read_size();
}
if (instance_type == STRING_TYPE ||
instance_type == INTERNALIZED_STRING_TYPE) {
// Strings may get concurrently truncated, hence we have to access its
// length synchronized.
return SeqTwoByteString::SizeFor(
SeqTwoByteString::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
return FixedDoubleArray::SizeFor(
FixedDoubleArray::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == FEEDBACK_METADATA_TYPE) {
return FeedbackMetadata::SizeFor(
FeedbackMetadata::unchecked_cast(*this)->synchronized_slot_count());
}
if (instance_type == DESCRIPTOR_ARRAY_TYPE) {
return DescriptorArray::SizeFor(
DescriptorArray::unchecked_cast(*this)->number_of_all_descriptors());
}
if (IsInRange(instance_type, FIRST_WEAK_FIXED_ARRAY_TYPE,
LAST_WEAK_FIXED_ARRAY_TYPE)) {
return WeakFixedArray::SizeFor(
WeakFixedArray::unchecked_cast(*this)->synchronized_length());
}
if (instance_type == WEAK_ARRAY_LIST_TYPE) {
return WeakArrayList::SizeForCapacity(
WeakArrayList::unchecked_cast(*this)->synchronized_capacity());
}
if (IsInRange(instance_type, FIRST_FIXED_TYPED_ARRAY_TYPE,
LAST_FIXED_TYPED_ARRAY_TYPE)) {
return FixedTypedArrayBase::unchecked_cast(*this)->TypedArraySize(
instance_type);
}
if (instance_type == SMALL_ORDERED_HASH_SET_TYPE) {
return SmallOrderedHashSet::SizeFor(
SmallOrderedHashSet::unchecked_cast(*this)->Capacity());
}
if (instance_type == SMALL_ORDERED_HASH_MAP_TYPE) {
return SmallOrderedHashMap::SizeFor(
SmallOrderedHashMap::unchecked_cast(*this)->Capacity());
}
if (instance_type == SMALL_ORDERED_NAME_DICTIONARY_TYPE) {
return SmallOrderedNameDictionary::SizeFor(
SmallOrderedNameDictionary::unchecked_cast(*this)->Capacity());
}
if (instance_type == PROPERTY_ARRAY_TYPE) {
return PropertyArray::SizeFor(
PropertyArray::cast(*this)->synchronized_length());
}
if (instance_type == FEEDBACK_VECTOR_TYPE) {
return FeedbackVector::SizeFor(
FeedbackVector::unchecked_cast(*this)->length());
}
if (instance_type == BIGINT_TYPE) {
return BigInt::SizeFor(BigInt::unchecked_cast(*this)->length());
}
if (instance_type == PREPARSE_DATA_TYPE) {
PreparseData data = PreparseData::unchecked_cast(*this);
return PreparseData::SizeFor(data->data_length(), data->children_length());
}
if (instance_type == CODE_TYPE) {
return Code::unchecked_cast(*this)->CodeSize();
}
DCHECK_EQ(instance_type, EMBEDDER_DATA_ARRAY_TYPE);
return EmbedderDataArray::SizeFor(
EmbedderDataArray::unchecked_cast(*this)->length());
}
bool HeapObject::NeedsRehashing() const {
switch (map()->instance_type()) {
case DESCRIPTOR_ARRAY_TYPE:
return DescriptorArray::cast(*this)->number_of_descriptors() > 1;
case TRANSITION_ARRAY_TYPE:
return TransitionArray::cast(*this)->number_of_entries() > 1;
case ORDERED_HASH_MAP_TYPE:
return OrderedHashMap::cast(*this)->NumberOfElements() > 0;
case ORDERED_HASH_SET_TYPE:
return OrderedHashSet::cast(*this)->NumberOfElements() > 0;
case NAME_DICTIONARY_TYPE:
case GLOBAL_DICTIONARY_TYPE:
case NUMBER_DICTIONARY_TYPE:
case SIMPLE_NUMBER_DICTIONARY_TYPE:
case STRING_TABLE_TYPE:
case HASH_TABLE_TYPE:
case SMALL_ORDERED_HASH_MAP_TYPE:
case SMALL_ORDERED_HASH_SET_TYPE:
case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
return true;
default:
return false;
}
}
bool HeapObject::CanBeRehashed() const {
DCHECK(NeedsRehashing());

View File

@ -634,23 +634,16 @@ class Object {
inline bool FitsRepresentation(Representation representation);
// Checks whether two valid primitive encodings of a property name resolve to
// the same logical property. E.g., the smi 1, the string "1" and the double
// 1 all refer to the same property, so this helper will return true.
inline bool KeyEquals(Object other);
inline bool FilterKey(PropertyFilter filter);
Handle<FieldType> OptimalType(Isolate* isolate,
Representation representation);
inline static Handle<Object> NewStorageFor(Isolate* isolate,
Handle<Object> object,
Representation representation);
static Handle<Object> NewStorageFor(Isolate* isolate, Handle<Object> object,
Representation representation);
inline static Handle<Object> WrapForRead(Isolate* isolate,
Handle<Object> object,
Representation representation);
static Handle<Object> WrapForRead(Isolate* isolate, Handle<Object> object,
Representation representation);
// Returns true if the object is of the correct type to be used as a
// implementation of a JSObject's elements.
@ -681,8 +674,8 @@ class Object {
V8_WARN_UNUSED_RESULT static inline MaybeHandle<JSReceiver> ToObject(
Isolate* isolate, Handle<Object> object,
const char* method_name = nullptr);
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> ToObject(
Isolate* isolate, Handle<Object> object, Handle<Context> native_context,
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> ToObjectImpl(
Isolate* isolate, Handle<Object> object,
const char* method_name = nullptr);
// ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.

View File

@ -738,6 +738,18 @@ int BytecodeArray::SizeIncludingMetadata() {
return size;
}
DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrBytecodeOffset, Smi)
DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
BailoutId DeoptimizationData::BytecodeOffset(int i) {
return BailoutId(BytecodeOffsetRaw(i)->value());
}

View File

@ -30,6 +30,9 @@ OBJECT_CONSTRUCTORS_IMPL(EnumCache, Tuple2)
CAST_ACCESSOR(DescriptorArray)
CAST_ACCESSOR(EnumCache)
ACCESSORS(EnumCache, keys, FixedArray, kKeysOffset)
ACCESSORS(EnumCache, indices, FixedArray, kIndicesOffset)
ACCESSORS(DescriptorArray, enum_cache, EnumCache, kEnumCacheOffset)
RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_all_descriptors,
kNumberOfAllDescriptorsOffset)

View File

@ -7,6 +7,7 @@
#include "src/objects/dictionary.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/oddball.h"
#include "src/objects/property-cell-inl.h"

View File

@ -17,6 +17,36 @@
namespace v8 {
namespace internal {
OBJECT_CONSTRUCTORS_IMPL(HashTableBase, FixedArray)
template <typename Derived, typename Shape>
HashTable<Derived, Shape>::HashTable(Address ptr) : HashTableBase(ptr) {
SLOW_DCHECK(IsHashTable());
}
template <typename Derived, typename Shape>
ObjectHashTableBase<Derived, Shape>::ObjectHashTableBase(Address ptr)
: HashTable<Derived, Shape>(ptr) {}
ObjectHashTable::ObjectHashTable(Address ptr)
: ObjectHashTableBase<ObjectHashTable, ObjectHashTableShape>(ptr) {
SLOW_DCHECK(IsObjectHashTable());
}
EphemeronHashTable::EphemeronHashTable(Address ptr)
: ObjectHashTableBase<EphemeronHashTable, EphemeronHashTableShape>(ptr) {
SLOW_DCHECK(IsEphemeronHashTable());
}
ObjectHashSet::ObjectHashSet(Address ptr)
: HashTable<ObjectHashSet, ObjectHashSetShape>(ptr) {
SLOW_DCHECK(IsObjectHashSet());
}
CAST_ACCESSOR(ObjectHashTable)
CAST_ACCESSOR(EphemeronHashTable)
CAST_ACCESSOR(ObjectHashSet)
int HashTableBase::NumberOfElements() const {
return Smi::ToInt(get(kNumberOfElementsIndex));
}

View File

@ -121,7 +121,7 @@ class HeapObject : public Object {
// Given a heap object's map pointer, returns the heap size in bytes
// Useful when the map pointer field is used for other purposes.
// GC internal.
inline int SizeFromMap(Map map) const;
V8_EXPORT_PRIVATE int SizeFromMap(Map map) const;
// Returns the field at offset in obj, as a read/write Object reference.
// Does no checking, and is safe to use during GC, while maps are invalid.
@ -164,7 +164,7 @@ class HeapObject : public Object {
// Whether the object needs rehashing. That is the case if the object's
// content depends on FLAG_hash_seed. When the object is deserialized into
// a heap with a different hash seed, these objects need to adapt.
inline bool NeedsRehashing() const;
bool NeedsRehashing() const;
// Rehashing support is not implemented for all objects that need rehashing.
// With objects that need rehashing but cannot be rehashed, rehashing has to

View File

@ -7,7 +7,8 @@
#include "src/objects/js-collection.h"
#include "src/objects-inl.h" // Needed for write barriers
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

View File

@ -8,6 +8,7 @@
#include "src/objects/js-objects.h"
#include "src/feedback-vector.h"
#include "src/field-index-inl.h"
#include "src/heap/heap-write-barrier.h"
#include "src/keys.h"
#include "src/lookup-inl.h"

View File

@ -340,6 +340,7 @@ Maybe<bool> JSReceiver::SetOrCopyDataProperties(
return Just(true);
}
String JSReceiver::class_name() {
ReadOnlyRoots roots = GetReadOnlyRoots();
if (IsFunction()) return roots.Function_string();

View File

@ -17,6 +17,8 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(ObjectBoilerplateDescription, FixedArray)
CAST_ACCESSOR(ObjectBoilerplateDescription)
SMI_ACCESSORS(ObjectBoilerplateDescription, flags,
FixedArray::OffsetOfElementAt(kLiteralTypeOffset));

View File

@ -13,7 +13,7 @@
#include "src/objects-inl.h"
#include "src/objects/api-callbacks-inl.h"
#include "src/objects/cell-inl.h"
#include "src/objects/descriptor-array.h"
#include "src/objects/descriptor-array-inl.h"
#include "src/objects/instance-type-inl.h"
#include "src/objects/prototype-info-inl.h"
#include "src/objects/shared-function-info.h"
@ -770,23 +770,19 @@ int Map::InstanceSizeFromSlack(int slack) const {
return instance_size() - slack * kTaggedSize;
}
OBJECT_CONSTRUCTORS_IMPL(NormalizedMapCache, WeakFixedArray)
CAST_ACCESSOR(NormalizedMapCache)
NEVER_READ_ONLY_SPACE_IMPL(NormalizedMapCache)
int NormalizedMapCache::GetIndex(Handle<Map> map) {
return map->Hash() % NormalizedMapCache::kEntries;
}
bool NormalizedMapCache::IsNormalizedMapCache(const HeapObject obj) {
if (!obj->IsWeakFixedArray()) return false;
if (WeakFixedArray::cast(obj)->length() != NormalizedMapCache::kEntries) {
bool HeapObject::IsNormalizedMapCache() const {
if (!IsWeakFixedArray()) return false;
if (WeakFixedArray::cast(*this)->length() != NormalizedMapCache::kEntries) {
return false;
}
#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
NormalizedMapCache cache = NormalizedMapCache::cast(obj);
cache->NormalizedMapCacheVerify(cache->GetIsolate());
}
#endif
return true;
}

View File

@ -22,7 +22,7 @@
#include "src/ostreams.h"
#include "src/property.h"
#include "src/roots.h"
#include "src/transitions.h"
#include "src/transitions-inl.h"
#include "src/zone/zone-containers.h"
namespace v8 {

View File

@ -1005,12 +1005,11 @@ class NormalizedMapCache : public WeakFixedArray {
void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
DECL_CAST(NormalizedMapCache)
static inline bool IsNormalizedMapCache(const HeapObject obj);
DECL_VERIFIER(NormalizedMapCache)
private:
friend bool HeapObject::IsNormalizedMapCache() const;
static const int kEntries = 64;
static inline int GetIndex(Handle<Map> map);

View File

@ -46,6 +46,11 @@ Handle<Object> Oddball::ToNumber(Isolate* isolate, Handle<Oddball> input) {
return handle(input->to_number(), isolate);
}
bool HeapObject::IsBoolean() const {
return IsOddball() &&
((Oddball::cast(*this)->kind() & Oddball::kNotBooleanMask) == 0);
}
} // namespace internal
} // namespace v8

View File

@ -107,6 +107,11 @@ CAST_ACCESSOR(UncompiledDataWithPreparseData)
ACCESSORS(UncompiledDataWithPreparseData, preparse_data, PreparseData,
kPreparseDataOffset)
bool HeapObject::IsUncompiledData() const {
return IsUncompiledDataWithoutPreparseData() ||
IsUncompiledDataWithPreparseData();
}
OBJECT_CONSTRUCTORS_IMPL(InterpreterData, Struct)
CAST_ACCESSOR(InterpreterData)

View File

@ -31,7 +31,7 @@
#include "src/profiler/heap-profiler.h"
#include "src/profiler/heap-snapshot-generator-inl.h"
#include "src/prototype.h"
#include "src/transitions.h"
#include "src/transitions-inl.h"
#include "src/visitors.h"
namespace v8 {

View File

@ -11,7 +11,8 @@
#include "src/handles.h"
#include "src/heap/heap-inl.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/descriptor-array.h"
#include "src/objects/descriptor-array-inl.h"
#include "src/objects/heap-number.h"
#include "src/objects/literal-objects.h"
#include "src/objects/map.h"
#include "src/objects/property-cell.h"

View File

@ -21,9 +21,11 @@
#include "src/objects/heap-number-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
#include "src/objects/promise-inl.h"
#include "src/objects/smi.h"
#include "src/objects/struct-inl.h"
#include "src/transitions-inl.h"
#include "test/cctest/compiler/code-assembler-tester.h"
#include "test/cctest/compiler/function-tester.h"

View File

@ -13,7 +13,7 @@
#include "src/global-handles.h"
#include "src/heap/factory.h"
#include "src/objects-inl.h"
#include "src/transitions.h"
#include "src/transitions-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/test-transitions.h"

View File

@ -313,6 +313,7 @@ header = '''
#include "src/frames-inl.h" /* for architecture-specific frame constants */
#include "src/contexts.h"
#include "src/objects.h"
#include "src/objects/data-handler.h"
#include "src/objects/js-promise.h"
#include "src/objects/js-regexp-string-iterator.h"