Commit 5c35f5e3 authored by titzer's avatar titzer Committed by Commit bot

Refactor the StackFrameIterator::ComputeType() method to look up the code...

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}
parent d1472d65
......@@ -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; }
......
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