Refactor the StackFrameIterator::ComputeType() method to look up the code object (if any) before looking at the magic markers.
This will allow per-code-kind logic more easily in the future (e.g. for WASM). BUG= Review URL: https://codereview.chromium.org/1350763004 Cr-Commit-Position: refs/heads/master@{#30912}
This commit is contained in:
parent
d1472d65dd
commit
5c35f5e302
@ -19,7 +19,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
ReturnAddressLocationResolver
|
||||
StackFrame::return_address_location_resolver_ = NULL;
|
||||
|
||||
@ -407,42 +406,58 @@ void StackFrame::SetReturnAddressLocationResolver(
|
||||
StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
|
||||
State* state) {
|
||||
DCHECK(state->fp != NULL);
|
||||
if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
|
||||
return ARGUMENTS_ADAPTOR;
|
||||
|
||||
if (!iterator->can_access_heap_objects_) {
|
||||
// TODO(titzer): "can_access_heap_objects" is kind of bogus. It really
|
||||
// means that we are being called from the profiler, which can interrupt
|
||||
// the VM with a signal at any arbitrary instruction, with essentially
|
||||
// anything on the stack. So basically none of these checks are 100%
|
||||
// reliable.
|
||||
if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
|
||||
// An adapter frame has a special SMI constant for the context and
|
||||
// is not distinguished through the marker.
|
||||
return ARGUMENTS_ADAPTOR;
|
||||
}
|
||||
Object* marker =
|
||||
Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset);
|
||||
if (marker->IsSmi()) {
|
||||
return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
|
||||
} else {
|
||||
return JAVA_SCRIPT;
|
||||
}
|
||||
}
|
||||
// The marker and function offsets overlap. If the marker isn't a
|
||||
// smi then the frame is a JavaScript frame -- and the marker is
|
||||
// really the function.
|
||||
const int offset = StandardFrameConstants::kMarkerOffset;
|
||||
Object* marker = Memory::Object_at(state->fp + offset);
|
||||
if (!marker->IsSmi()) {
|
||||
// If we're using a "safe" stack iterator, we treat optimized
|
||||
// frames as normal JavaScript frames to avoid having to look
|
||||
// into the heap to determine the state. This is safe as long
|
||||
// as nobody tries to GC...
|
||||
if (!iterator->can_access_heap_objects_) return JAVA_SCRIPT;
|
||||
Code* code_obj =
|
||||
GetContainingCode(iterator->isolate(), *(state->pc_address));
|
||||
|
||||
// Look up the code object to figure out the type of the stack frame.
|
||||
Code* code_obj = GetContainingCode(iterator->isolate(), *(state->pc_address));
|
||||
|
||||
Object* marker =
|
||||
Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset);
|
||||
if (code_obj != nullptr) {
|
||||
switch (code_obj->kind()) {
|
||||
case Code::FUNCTION:
|
||||
return JAVA_SCRIPT;
|
||||
|
||||
case Code::HANDLER:
|
||||
#ifdef DEBUG
|
||||
if (!code_obj->is_hydrogen_stub()) {
|
||||
// There's currently no support for non-hydrogen stub handlers. If
|
||||
// you this, you'll have to implement it yourself.
|
||||
UNREACHABLE();
|
||||
}
|
||||
#endif
|
||||
case Code::OPTIMIZED_FUNCTION:
|
||||
return OPTIMIZED;
|
||||
|
||||
case Code::HANDLER:
|
||||
if (!marker->IsSmi()) {
|
||||
// Only hydrogen code stub handlers can have a non-SMI marker.
|
||||
DCHECK(code_obj->is_hydrogen_stub());
|
||||
return OPTIMIZED;
|
||||
}
|
||||
break; // Marker encodes the frame type.
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return JAVA_SCRIPT;
|
||||
break; // Marker encodes the frame type.
|
||||
}
|
||||
}
|
||||
|
||||
if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
|
||||
// An adapter frame has a special SMI constant for the context and
|
||||
// is not distinguished through the marker.
|
||||
return ARGUMENTS_ADAPTOR;
|
||||
}
|
||||
|
||||
// Didn't find a code object, or the code kind wasn't specific enough.
|
||||
// The marker should encode the frame type.
|
||||
return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
|
||||
}
|
||||
|
||||
@ -1445,6 +1460,11 @@ Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object,
|
||||
Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
|
||||
Address inner_pointer) {
|
||||
Heap* heap = isolate_->heap();
|
||||
if (!heap->code_space()->Contains(inner_pointer) &&
|
||||
!heap->lo_space()->Contains(inner_pointer)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check if the inner pointer points into a large object chunk.
|
||||
LargePage* large_page = heap->lo_space()->FindPage(inner_pointer);
|
||||
if (large_page != NULL) {
|
||||
|
@ -3033,6 +3033,11 @@ bool LargeObjectSpace::Contains(HeapObject* object) {
|
||||
}
|
||||
|
||||
|
||||
bool LargeObjectSpace::Contains(Address address) {
|
||||
return FindPage(address) != NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef VERIFY_HEAP
|
||||
// We do not assume that the large object iterator works, because it depends
|
||||
// on the invariants we are checking during verification.
|
||||
|
@ -2889,6 +2889,7 @@ class LargeObjectSpace : public Space {
|
||||
|
||||
// Checks whether a heap object is in this space; O(1).
|
||||
bool Contains(HeapObject* obj);
|
||||
bool Contains(Address address);
|
||||
|
||||
// Checks whether the space is empty.
|
||||
bool IsEmpty() { return first_page_ == NULL; }
|
||||
|
Loading…
Reference in New Issue
Block a user