[ubsan] Port Struct subclasses, part 10

Tuple2 and subclasses: EnumCache, SourcePositionTableWithFrameCache,
TemplateObjectDescription

Bug: v8:3770
Change-Id: Icff0860a04445dda542119834ef9866167ba2263
Reviewed-on: https://chromium-review.googlesource.com/c/1377772
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58287}
This commit is contained in:
Jakob Kummerow 2018-12-17 07:05:27 -08:00 committed by Commit Bot
parent fa3cbf60d5
commit 7520a0fab8
18 changed files with 46 additions and 88 deletions

View File

@ -2203,7 +2203,7 @@ void MarkCompactCollector::TrimEnumCache(Map map, DescriptorArray descriptors) {
live_enum = map->NumberOfEnumerableProperties();
}
if (live_enum == 0) return descriptors->ClearEnumCache();
EnumCache* enum_cache = descriptors->enum_cache();
EnumCache enum_cache = descriptors->enum_cache();
FixedArray keys = enum_cache->keys();
int to_trim = keys->length() - live_enum;

View File

@ -778,7 +778,7 @@ void ObjectStatsCollectorImpl::RecordVirtualMapDetails(Map map) {
if (map->owns_descriptors() &&
array != ReadOnlyRoots(heap_).empty_descriptor_array()) {
// DescriptorArray has its own instance type.
EnumCache* enum_cache = array->enum_cache();
EnumCache enum_cache = array->enum_cache();
RecordSimpleVirtualObjectStats(array, enum_cache->keys(),
ObjectStats::ENUM_CACHE_TYPE);
RecordSimpleVirtualObjectStats(array, enum_cache->indices(),

View File

@ -620,7 +620,7 @@ void JSObject::JSObjectVerify(Isolate* isolate) {
}
if (map()->EnumLength() != kInvalidEnumCacheSentinel) {
EnumCache* enum_cache = descriptors->enum_cache();
EnumCache enum_cache = descriptors->enum_cache();
FixedArray keys = enum_cache->keys();
FixedArray indices = enum_cache->indices();
CHECK_LE(map()->EnumLength(), keys->length());
@ -1761,21 +1761,17 @@ void PrototypeUsers::Verify(WeakArrayList array) {
void Tuple2::Tuple2Verify(Isolate* isolate) {
CHECK(IsTuple2());
Heap* heap = isolate->heap();
if (this == ReadOnlyRoots(heap).empty_enum_cache()) {
if (*this == ReadOnlyRoots(heap).empty_enum_cache()) {
CHECK_EQ(ReadOnlyRoots(heap).empty_fixed_array(),
EnumCache::cast(this)->keys());
EnumCache::cast(*this)->keys());
CHECK_EQ(ReadOnlyRoots(heap).empty_fixed_array(),
EnumCache::cast(this)->indices());
EnumCache::cast(*this)->indices());
} else {
VerifyObjectField(isolate, kValue1Offset);
VerifyObjectField(isolate, kValue2Offset);
}
}
void Tuple2Ptr::Tuple2Verify(Isolate* isolate) {
reinterpret_cast<Tuple2*>(ptr())->Tuple2Verify(isolate);
}
void Tuple3::Tuple3Verify(Isolate* isolate) {
CHECK(IsTuple3());
VerifyObjectField(isolate, kValue1Offset);

View File

@ -456,13 +456,14 @@ OBJECT_CONSTRUCTORS_IMPL(BigIntBase, HeapObjectPtr)
OBJECT_CONSTRUCTORS_IMPL(BigInt, BigIntBase)
OBJECT_CONSTRUCTORS_IMPL(FreshlyAllocatedBigInt, BigIntBase)
OBJECT_CONSTRUCTORS_IMPL(TemplateObjectDescription, Tuple2)
// ------------------------------------
// Cast operations
CAST_ACCESSOR2(BigInt)
CAST_ACCESSOR2(ObjectBoilerplateDescription)
CAST_ACCESSOR2(EphemeronHashTable)
CAST_ACCESSOR(EnumCache)
CAST_ACCESSOR(HeapObject)
CAST_ACCESSOR(HeapNumber)
CAST_ACCESSOR(MutableHeapNumber)
@ -473,7 +474,7 @@ CAST_ACCESSOR2(ObjectHashTable)
CAST_ACCESSOR(Oddball)
CAST_ACCESSOR2(RegExpMatchInfo)
CAST_ACCESSOR2(ScopeInfo)
CAST_ACCESSOR(TemplateObjectDescription)
CAST_ACCESSOR2(TemplateObjectDescription)
bool Object::HasValidElements() {
// Dictionary is covered under FixedArray.

View File

@ -1729,16 +1729,12 @@ void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) { // NOLINT
}
void Tuple2::Tuple2Print(std::ostream& os) { // NOLINT
HeapObject::PrintHeader(os, "Tuple2");
PrintHeader(os, "Tuple2");
os << "\n - value1: " << Brief(value1());
os << "\n - value2: " << Brief(value2());
os << "\n";
}
void Tuple2Ptr::Tuple2Print(std::ostream& os) { // NOLINT
reinterpret_cast<Tuple2*>(ptr())->Tuple2Print(os);
}
void Tuple3::Tuple3Print(std::ostream& os) { // NOLINT
PrintHeader(os, "Tuple3");
os << "\n - value1: " << Brief(value1());

View File

@ -3771,10 +3771,6 @@ void Tuple2::BriefPrintDetails(std::ostream& os) {
os << " " << Brief(value1()) << ", " << Brief(value2());
}
void Tuple2Ptr::BriefPrintDetails(std::ostream& os) {
os << " " << Brief(value1()) << ", " << Brief(value2());
}
void Tuple3::BriefPrintDetails(std::ostream& os) {
os << " " << Brief(value1()) << ", " << Brief(value2()) << ", "
<< Brief(value3());
@ -10776,7 +10772,7 @@ Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
pretenure);
}
void DescriptorArray::Initialize(EnumCache* enum_cache,
void DescriptorArray::Initialize(EnumCache enum_cache,
HeapObject* undefined_value,
int nof_descriptors, int slack) {
DCHECK_GE(nof_descriptors, 0);
@ -10804,7 +10800,7 @@ void DescriptorArray::Replace(int index, Descriptor* descriptor) {
void DescriptorArray::InitializeOrChangeEnumCache(
Handle<DescriptorArray> descriptors, Isolate* isolate,
Handle<FixedArray> keys, Handle<FixedArray> indices) {
EnumCache* enum_cache = descriptors->enum_cache();
EnumCache enum_cache = descriptors->enum_cache();
if (enum_cache == ReadOnlyRoots(isolate).empty_enum_cache()) {
enum_cache = *isolate->factory()->NewEnumCache(keys, indices);
descriptors->set_enum_cache(enum_cache);
@ -13643,7 +13639,7 @@ Handle<String> JSFunction::ToString(Handle<JSFunction> function) {
Handle<Object> maybe_class_positions = JSReceiver::GetDataProperty(
function, isolate->factory()->class_positions_symbol());
if (maybe_class_positions->IsTuple2()) {
Tuple2* class_positions = Tuple2::cast(*maybe_class_positions);
Tuple2 class_positions = Tuple2::cast(*maybe_class_positions);
int start_position = Smi::ToInt(class_positions->value1());
int end_position = Smi::ToInt(class_positions->value2());
Handle<String> script_source(

View File

@ -27,6 +27,7 @@ OBJECT_CONSTRUCTORS_IMPL(BytecodeArray, FixedArrayBase)
OBJECT_CONSTRUCTORS_IMPL(AbstractCode, HeapObjectPtr)
OBJECT_CONSTRUCTORS_IMPL(DependentCode, WeakFixedArray)
OBJECT_CONSTRUCTORS_IMPL(CodeDataContainer, HeapObjectPtr)
OBJECT_CONSTRUCTORS_IMPL(SourcePositionTableWithFrameCache, Tuple2)
NEVER_READ_ONLY_SPACE_IMPL(AbstractCode)
@ -36,7 +37,7 @@ CAST_ACCESSOR2(Code)
CAST_ACCESSOR2(CodeDataContainer)
CAST_ACCESSOR2(DependentCode)
CAST_ACCESSOR2(DeoptimizationData)
CAST_ACCESSOR(SourcePositionTableWithFrameCache)
CAST_ACCESSOR2(SourcePositionTableWithFrameCache)
ACCESSORS2(SourcePositionTableWithFrameCache, source_position_table, ByteArray,
kSourcePositionTableIndex)

View File

@ -921,7 +921,7 @@ class SourcePositionTableWithFrameCache : public Tuple2 {
DECL_ACCESSORS2(source_position_table, ByteArray)
DECL_ACCESSORS2(stack_frame_cache, SimpleNumberDictionary)
DECL_CAST(SourcePositionTableWithFrameCache)
DECL_CAST2(SourcePositionTableWithFrameCache)
// Layout description.
#define SOURCE_POSITION_TABLE_WITH_FRAME_FIELDS(V) \
@ -934,8 +934,7 @@ class SourcePositionTableWithFrameCache : public Tuple2 {
SOURCE_POSITION_TABLE_WITH_FRAME_FIELDS)
#undef SOURCE_POSITION_TABLE_WITH_FRAME_FIELDS
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SourcePositionTableWithFrameCache);
OBJECT_CONSTRUCTORS(SourcePositionTableWithFrameCache, Tuple2);
};
} // namespace internal

View File

@ -18,8 +18,8 @@
namespace v8 {
namespace internal {
OBJECT_CONSTRUCTORS_IMPL(BreakPoint, Tuple2Ptr)
OBJECT_CONSTRUCTORS_IMPL(BreakPointInfo, Tuple2Ptr)
OBJECT_CONSTRUCTORS_IMPL(BreakPoint, Tuple2)
OBJECT_CONSTRUCTORS_IMPL(BreakPointInfo, Tuple2)
OBJECT_CONSTRUCTORS_IMPL(CoverageInfo, FixedArray)
OBJECT_CONSTRUCTORS_IMPL(DebugInfo, StructPtr)

View File

@ -196,7 +196,7 @@ class DebugInfo : public StructPtr {
// The BreakPointInfo class holds information for break points set in a
// function. The DebugInfo object holds a BreakPointInfo object for each code
// position with one or more break points.
class BreakPointInfo : public Tuple2Ptr {
class BreakPointInfo : public Tuple2 {
public:
// The position in the source for the break position.
DECL_INT_ACCESSORS(source_position)
@ -222,7 +222,7 @@ class BreakPointInfo : public Tuple2Ptr {
static const int kSourcePositionOffset = kValue1Offset;
static const int kBreakPointsOffset = kValue2Offset;
OBJECT_CONSTRUCTORS(BreakPointInfo, Tuple2Ptr);
OBJECT_CONSTRUCTORS(BreakPointInfo, Tuple2);
};
// Holds information related to block code coverage.
@ -265,7 +265,7 @@ class CoverageInfo : public FixedArray {
};
// Holds breakpoint related information. This object is used by inspector.
class BreakPoint : public Tuple2Ptr {
class BreakPoint : public Tuple2 {
public:
DECL_INT_ACCESSORS(id)
DECL_ACCESSORS2(condition, String)
@ -275,7 +275,7 @@ class BreakPoint : public Tuple2Ptr {
static const int kIdOffset = kValue1Offset;
static const int kConditionOffset = kValue2Offset;
OBJECT_CONSTRUCTORS(BreakPoint, Tuple2Ptr);
OBJECT_CONSTRUCTORS(BreakPoint, Tuple2);
};
} // namespace internal

View File

@ -24,10 +24,12 @@ namespace v8 {
namespace internal {
OBJECT_CONSTRUCTORS_IMPL(DescriptorArray, HeapObjectPtr)
OBJECT_CONSTRUCTORS_IMPL(EnumCache, Tuple2)
CAST_ACCESSOR2(DescriptorArray)
CAST_ACCESSOR2(EnumCache)
ACCESSORS(DescriptorArray, enum_cache, EnumCache, kEnumCacheOffset)
ACCESSORS2(DescriptorArray, enum_cache, EnumCache, kEnumCacheOffset)
RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_all_descriptors,
kNumberOfAllDescriptorsOffset)
RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_descriptors,

View File

@ -26,14 +26,13 @@ class EnumCache : public Tuple2 {
DECL_ACCESSORS2(keys, FixedArray)
DECL_ACCESSORS2(indices, FixedArray)
DECL_CAST(EnumCache)
DECL_CAST2(EnumCache)
// Layout description.
static const int kKeysOffset = kValue1Offset;
static const int kIndicesOffset = kValue2Offset;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(EnumCache);
OBJECT_CONSTRUCTORS(EnumCache, Tuple2);
};
// A DescriptorArray is a custom array that holds instance descriptors.
@ -59,7 +58,7 @@ class DescriptorArray : public HeapObjectPtr {
DECL_INT16_ACCESSORS(number_of_descriptors)
inline int16_t number_of_slack_descriptors() const;
inline int number_of_entries() const;
DECL_ACCESSORS(enum_cache, EnumCache)
DECL_ACCESSORS2(enum_cache, EnumCache)
void ClearEnumCache();
inline void CopyEnumCacheFrom(DescriptorArray array);
@ -127,7 +126,7 @@ class DescriptorArray : public HeapObjectPtr {
Isolate* isolate, int nof_descriptors, int slack,
PretenureFlag pretenure = NOT_TENURED);
void Initialize(EnumCache* enum_cache, HeapObject* undefined_value,
void Initialize(EnumCache enum_cache, HeapObject* undefined_value,
int nof_descriptors, int slack);
DECL_CAST2(DescriptorArray)

View File

@ -18,22 +18,18 @@ namespace internal {
bool StructPtr::IsStructPtr() const {
return reinterpret_cast<Struct*>(ptr())->IsStruct();
}
bool Tuple2Ptr::IsTuple2Ptr() const {
return reinterpret_cast<Tuple2*>(ptr())->IsTuple2();
}
OBJECT_CONSTRUCTORS_IMPL(StructPtr, HeapObjectPtr)
// TODO(jkummerow): Fix IsTuple2() and IsTuple3() to be subclassing-aware,
// or rethink this more generally (see crbug.com/v8/8516).
Tuple2Ptr::Tuple2Ptr(Address ptr) : StructPtr(ptr) {}
Tuple3::Tuple3(Address ptr) : Tuple2Ptr(ptr) {}
Tuple2::Tuple2(Address ptr) : StructPtr(ptr) {}
Tuple3::Tuple3(Address ptr) : Tuple2(ptr) {}
OBJECT_CONSTRUCTORS_IMPL(AccessorPair, StructPtr)
CAST_ACCESSOR2(AccessorPair)
CAST_ACCESSOR(Struct)
CAST_ACCESSOR2(StructPtr)
CAST_ACCESSOR(Tuple2)
CAST_ACCESSOR2(Tuple2Ptr)
CAST_ACCESSOR2(Tuple2)
CAST_ACCESSOR2(Tuple3)
void Struct::InitializeBody(int object_size) {
@ -51,9 +47,7 @@ void StructPtr::InitializeBody(int object_size) {
}
ACCESSORS(Tuple2, value1, Object, kValue1Offset)
ACCESSORS(Tuple2Ptr, value1, Object, kValue1Offset)
ACCESSORS(Tuple2, value2, Object, kValue2Offset)
ACCESSORS(Tuple2Ptr, value2, Object, kValue2Offset)
ACCESSORS(Tuple3, value3, Object, kValue3Offset)
ACCESSORS(AccessorPair, getter, Object, kGetterOffset)

View File

@ -38,12 +38,12 @@ class StructPtr : public HeapObjectPtr {
OBJECT_CONSTRUCTORS(StructPtr, HeapObjectPtr);
};
class Tuple2 : public Struct {
class Tuple2 : public StructPtr {
public:
DECL_ACCESSORS(value1, Object)
DECL_ACCESSORS(value2, Object)
DECL_CAST(Tuple2)
DECL_CAST2(Tuple2)
// Dispatched behavior.
DECL_PRINTER(Tuple2)
@ -54,35 +54,10 @@ class Tuple2 : public Struct {
static const int kValue2Offset = kValue1Offset + kPointerSize;
static const int kSize = kValue2Offset + kPointerSize;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Tuple2);
OBJECT_CONSTRUCTORS(Tuple2, StructPtr);
};
// Replacement for the above, temporarily separate for incremental transition
// of subclasses.
class Tuple2Ptr : public StructPtr {
public:
DECL_ACCESSORS(value1, Object)
DECL_ACCESSORS(value2, Object)
DECL_CAST2(Tuple2Ptr)
// Dispatched behavior.
DECL_PRINTER(Tuple2)
DECL_VERIFIER(Tuple2)
void BriefPrintDetails(std::ostream& os);
// TODO(3770): Temporary.
inline bool IsTuple2Ptr() const;
static const int kValue1Offset = HeapObject::kHeaderSize;
static const int kValue2Offset = kValue1Offset + kPointerSize;
static const int kSize = kValue2Offset + kPointerSize;
OBJECT_CONSTRUCTORS(Tuple2Ptr, StructPtr);
};
class Tuple3 : public Tuple2Ptr {
class Tuple3 : public Tuple2 {
public:
DECL_ACCESSORS(value3, Object)
@ -96,7 +71,7 @@ class Tuple3 : public Tuple2Ptr {
static const int kValue3Offset = Tuple2::kSize;
static const int kSize = kValue3Offset + kPointerSize;
OBJECT_CONSTRUCTORS(Tuple3, Tuple2Ptr);
OBJECT_CONSTRUCTORS(Tuple3, Tuple2);
};
// Support for JavaScript accessors: A pair of a getter and a setter. Each

View File

@ -27,13 +27,12 @@ class TemplateObjectDescription final : public Tuple2 {
static Handle<JSArray> CreateTemplateObject(
Isolate* isolate, Handle<TemplateObjectDescription> description);
DECL_CAST(TemplateObjectDescription)
DECL_CAST2(TemplateObjectDescription)
static constexpr int kRawStringsOffset = kValue1Offset;
static constexpr int kCookedStringsOffset = kValue2Offset;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateObjectDescription);
OBJECT_CONSTRUCTORS(TemplateObjectDescription, Tuple2);
};
} // namespace internal

View File

@ -178,7 +178,7 @@ class RootVisitor;
V(Map, stale_register_map, StaleRegisterMap) \
V(Map, self_reference_marker_map, SelfReferenceMarkerMap) \
/* Canonical empty values */ \
V(EnumCache*, empty_enum_cache, EmptyEnumCache) \
V(EnumCache, empty_enum_cache, EmptyEnumCache) \
V(PropertyArray, empty_property_array, EmptyPropertyArray) \
V(ByteArray, empty_byte_array, EmptyByteArray) \
V(ObjectBoilerplateDescription, empty_object_boilerplate_description, \

View File

@ -1210,7 +1210,7 @@ WasmInstanceObject ImportedFunctionEntry::instance() {
if (value->IsWasmInstanceObject()) {
return WasmInstanceObject::cast(value);
}
Tuple2* tuple = Tuple2::cast(value);
Tuple2 tuple = Tuple2::cast(value);
return WasmInstanceObject::cast(tuple->value1());
}

View File

@ -148,7 +148,7 @@ TEST(EnumCache) {
CHECK_EQ(c->map()->instance_descriptors()->enum_cache(),
*factory->empty_enum_cache());
EnumCache* enum_cache = cc->map()->instance_descriptors()->enum_cache();
EnumCache enum_cache = cc->map()->instance_descriptors()->enum_cache();
CHECK_NE(enum_cache, *factory->empty_enum_cache());
CHECK_EQ(enum_cache->keys()->length(), 3);
CHECK_EQ(enum_cache->indices()->length(), 3);
@ -165,7 +165,7 @@ TEST(EnumCache) {
// The enum cache is shared on the descriptor array of maps {a}, {b} and
// {c} only.
EnumCache* enum_cache = a->map()->instance_descriptors()->enum_cache();
EnumCache enum_cache = a->map()->instance_descriptors()->enum_cache();
CHECK_NE(enum_cache, *factory->empty_enum_cache());
CHECK_NE(cc->map()->instance_descriptors()->enum_cache(),
*factory->empty_enum_cache());
@ -193,7 +193,7 @@ TEST(EnumCache) {
CHECK_EQ(c->map()->EnumLength(), 3);
CHECK_EQ(cc->map()->EnumLength(), 3);
EnumCache* enum_cache = c->map()->instance_descriptors()->enum_cache();
EnumCache enum_cache = c->map()->instance_descriptors()->enum_cache();
CHECK_NE(enum_cache, *factory->empty_enum_cache());
// The keys and indices caches are updated.
CHECK_EQ(enum_cache, *previous_enum_cache);
@ -229,7 +229,7 @@ TEST(EnumCache) {
CHECK_EQ(c->map()->EnumLength(), 3);
CHECK_EQ(cc->map()->EnumLength(), 3);
EnumCache* enum_cache = c->map()->instance_descriptors()->enum_cache();
EnumCache enum_cache = c->map()->instance_descriptors()->enum_cache();
CHECK_NE(enum_cache, *factory->empty_enum_cache());
// The keys and indices caches are not updated.
CHECK_EQ(enum_cache, *previous_enum_cache);