[profiler] Don't cast bytecode array to avoid heap DCHECKs
When iterating over stack frames in the cpu profiler, don't perform any object casts that have heap-testing DCHECKs. Instead, access values on the frame by offsets directly, and only check their tags for validity. Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Change-Id: Ia54b18f8ab947c1827f17483806104f0d1d34136 Reviewed-on: https://chromium-review.googlesource.com/536973 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Cr-Commit-Position: refs/heads/master@{#45985}
This commit is contained in:
parent
8bc4fe57a4
commit
86b3b92230
@ -743,7 +743,11 @@ struct AccessorDescriptor {
|
||||
// Testers for test.
|
||||
|
||||
#define HAS_SMI_TAG(value) \
|
||||
((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag)
|
||||
((reinterpret_cast<intptr_t>(value) & ::i::kSmiTagMask) == ::i::kSmiTag)
|
||||
|
||||
#define HAS_HEAP_OBJECT_TAG(value) \
|
||||
(((reinterpret_cast<intptr_t>(value) & ::i::kHeapObjectTagMask) == \
|
||||
::i::kHeapObjectTag))
|
||||
|
||||
// OBJECT_POINTER_ALIGN returns the value aligned as a HeapObject pointer
|
||||
#define OBJECT_POINTER_ALIGN(value) \
|
||||
|
@ -242,19 +242,28 @@ bool TickSample::GetStackSample(Isolate* v8_isolate, RegisterState* regs,
|
||||
timer = timer->parent();
|
||||
}
|
||||
if (i == frames_limit) break;
|
||||
if (!it.frame()->is_interpreted()) {
|
||||
frames[i++] = it.frame()->pc();
|
||||
continue;
|
||||
if (it.frame()->is_interpreted()) {
|
||||
// For interpreted frames use the bytecode array pointer as the pc.
|
||||
i::InterpretedFrame* frame =
|
||||
static_cast<i::InterpretedFrame*>(it.frame());
|
||||
// Since the sampler can interrupt execution at any point the
|
||||
// bytecode_array might be garbage, so don't actually dereference it. We
|
||||
// avoid the frame->GetXXX functions since they call BytecodeArray::cast,
|
||||
// which has a heap access in its DCHECK.
|
||||
i::Object* bytecode_array = i::Memory::Object_at(
|
||||
frame->fp() + i::InterpreterFrameConstants::kBytecodeArrayFromFp);
|
||||
i::Object* bytecode_offset = i::Memory::Object_at(
|
||||
frame->fp() + i::InterpreterFrameConstants::kBytecodeOffsetFromFp);
|
||||
|
||||
// If the bytecode array is a heap object and the bytecode offset is a
|
||||
// Smi, use those, otherwise fall back to using the frame's pc.
|
||||
if (HAS_HEAP_OBJECT_TAG(bytecode_array) && HAS_SMI_TAG(bytecode_offset)) {
|
||||
frames[i++] = reinterpret_cast<i::Address>(bytecode_array) +
|
||||
i::Internals::SmiValue(bytecode_offset);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// For interpreted frames use the bytecode array pointer as the pc.
|
||||
i::InterpretedFrame* frame = static_cast<i::InterpretedFrame*>(it.frame());
|
||||
// Since the sampler can interrupt execution at any point the
|
||||
// bytecode_array might be garbage, so don't dereference it.
|
||||
i::Address bytecode_array =
|
||||
reinterpret_cast<i::Address>(frame->GetBytecodeArray()) -
|
||||
i::kHeapObjectTag;
|
||||
frames[i++] = bytecode_array + i::BytecodeArray::kHeaderSize +
|
||||
frame->GetBytecodeOffset();
|
||||
frames[i++] = it.frame()->pc();
|
||||
}
|
||||
sample_info->frames_count = i;
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user