Commit 9941c1e3 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Fix debug mode race in string casting in concurrent marker.

Bug: v8:6915, chromium:694255
Change-Id: I16cd8f13087476a16c7647bec3d03665299ef232
Reviewed-on: https://chromium-review.googlesource.com/712044
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48448}
parent 6e641ea3
......@@ -80,6 +80,11 @@ class ConcurrentMarkingVisitor final
marking_state_(live_bytes),
task_id_(task_id) {}
template <typename T>
static V8_INLINE T* Cast(HeapObject* object) {
return T::cast(object);
}
bool ShouldVisit(HeapObject* object) {
return marking_state_.GreyToBlack(object);
}
......@@ -344,6 +349,33 @@ class ConcurrentMarkingVisitor final
SlotSnapshot slot_snapshot_;
};
// Strings can change maps due to conversion to thin string or external strings.
// Use reinterpret cast to avoid data race in slow dchecks.
template <>
ConsString* ConcurrentMarkingVisitor::Cast(HeapObject* object) {
return reinterpret_cast<ConsString*>(object);
}
template <>
SlicedString* ConcurrentMarkingVisitor::Cast(HeapObject* object) {
return reinterpret_cast<SlicedString*>(object);
}
template <>
ThinString* ConcurrentMarkingVisitor::Cast(HeapObject* object) {
return reinterpret_cast<ThinString*>(object);
}
template <>
SeqOneByteString* ConcurrentMarkingVisitor::Cast(HeapObject* object) {
return reinterpret_cast<SeqOneByteString*>(object);
}
template <>
SeqTwoByteString* ConcurrentMarkingVisitor::Cast(HeapObject* object) {
return reinterpret_cast<SeqTwoByteString*>(object);
}
class ConcurrentMarking::Task : public CancelableTask {
public:
Task(Isolate* isolate, ConcurrentMarking* concurrent_marking,
......
......@@ -16,6 +16,12 @@
namespace v8 {
namespace internal {
template <typename ResultType, typename ConcreteVisitor>
template <typename T>
T* HeapVisitor<ResultType, ConcreteVisitor>::Cast(HeapObject* object) {
return T::cast(object);
}
template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(HeapObject* object) {
return Visit(object->map(), object);
......@@ -26,23 +32,28 @@ ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(Map* map,
HeapObject* object) {
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
switch (static_cast<VisitorId>(map->visitor_id())) {
#define CASE(type) \
case kVisit##type: \
return visitor->Visit##type(map, type::cast(object));
#define CASE(type) \
case kVisit##type: \
return visitor->Visit##type(map, \
ConcreteVisitor::template Cast<type>(object));
TYPED_VISITOR_ID_LIST(CASE)
#undef CASE
case kVisitShortcutCandidate:
return visitor->VisitShortcutCandidate(map, ConsString::cast(object));
return visitor->VisitShortcutCandidate(
map, ConcreteVisitor::template Cast<ConsString>(object));
case kVisitNativeContext:
return visitor->VisitNativeContext(map, Context::cast(object));
return visitor->VisitNativeContext(
map, ConcreteVisitor::template Cast<Context>(object));
case kVisitDataObject:
return visitor->VisitDataObject(map, HeapObject::cast(object));
return visitor->VisitDataObject(map, object);
case kVisitJSObjectFast:
return visitor->VisitJSObjectFast(map, JSObject::cast(object));
return visitor->VisitJSObjectFast(
map, ConcreteVisitor::template Cast<JSObject>(object));
case kVisitJSApiObject:
return visitor->VisitJSApiObject(map, JSObject::cast(object));
return visitor->VisitJSApiObject(
map, ConcreteVisitor::template Cast<JSObject>(object));
case kVisitStruct:
return visitor->VisitStruct(map, HeapObject::cast(object));
return visitor->VisitStruct(map, object);
case kVisitFreeSpace:
return visitor->VisitFreeSpace(map, FreeSpace::cast(object));
case kVisitorIdCount:
......@@ -78,13 +89,7 @@ TYPED_VISITOR_ID_LIST(VISIT)
template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitShortcutCandidate(
Map* map, ConsString* object) {
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
if (!visitor->ShouldVisit(object)) return ResultType();
int size = ConsString::BodyDescriptor::SizeOf(map, object);
if (visitor->ShouldVisitMapPointer())
visitor->VisitMapPointer(object, object->map_slot());
ConsString::BodyDescriptor::IterateBody(object, size, visitor);
return static_cast<ResultType>(size);
return static_cast<ConcreteVisitor*>(this)->VisitConsString(map, object);
}
template <typename ResultType, typename ConcreteVisitor>
......
......@@ -87,6 +87,9 @@ class HeapVisitor : public ObjectVisitor {
V8_INLINE ResultType VisitJSApiObject(Map* map, JSObject* object);
V8_INLINE ResultType VisitStruct(Map* map, HeapObject* object);
V8_INLINE ResultType VisitFreeSpace(Map* map, FreeSpace* object);
template <typename T>
static V8_INLINE T* Cast(HeapObject* object);
};
template <typename ConcreteVisitor>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment