Index: src/frames.cc |
diff --git a/src/frames.cc b/src/frames.cc |
index 2ddb4200bfaedc450fa8db611711f64af717b771..077131b8260016204c461fc01b0fab22f2747706 100644 |
--- a/src/frames.cc |
+++ b/src/frames.cc |
@@ -19,6 +19,8 @@ |
namespace v8 { |
namespace internal { |
+#define TRACE(...) |
+ |
ReturnAddressLocationResolver |
StackFrame::return_address_location_resolver_ = NULL; |
@@ -407,42 +409,75 @@ void StackFrame::SetReturnAddressLocationResolver( |
StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, |
State* state) { |
DCHECK(state->fp != NULL); |
- if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
- return ARGUMENTS_ADAPTOR; |
+ |
+ TRACE("StackFrame::ComputeType pc=%p context=%p, marker=%p ", |
+ reinterpret_cast<void*>(*(state->pc_address)), |
+ reinterpret_cast<void*>(Memory::Object_at( |
+ state->fp + StandardFrameConstants::kContextOffset)), |
+ reinterpret_cast<void*>(Memory::Object_at( |
+ state->fp + StandardFrameConstants::kMarkerOffset))); |
+ |
+ if (!iterator->can_access_heap_objects_) { |
+ TRACE("(safe iterator) "); |
+ // TODO(titzer): this is totally bogus. We're hunting around on random |
+ // stacks without a clue. But whatever. Profiling. |
+ if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
+ // An adapter frame has a special SMI constant for the context and |
+ // is not distinguished through the marker. |
+ TRACE("ARGUMENTS_ADAPTOR\n"); |
+ return ARGUMENTS_ADAPTOR; |
+ } |
+ Object* marker = |
+ Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); |
+ if (marker->IsSmi()) { |
+ TRACE("MARKER = %d\n", Smi::cast(marker)->value()); |
+ return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
+ } else { |
+ TRACE("JAVA_SCRIPT\n"); |
+ 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) { |
+ TRACE("(code kind = %d) ", static_cast<int>(code_obj->kind())); |
switch (code_obj->kind()) { |
case Code::FUNCTION: |
+ TRACE("JAVA_SCRIPT\n"); |
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: |
+ TRACE("OPTIMIZED\n"); |
return OPTIMIZED; |
- |
+ case Code::HANDLER: |
+ TRACE("(handler) \n"); |
+ 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. |
+ TRACE("ARGUMENTS_ADAPTOR\n"); |
+ return ARGUMENTS_ADAPTOR; |
+ } |
+ |
+ // Didn't find a code object, or the code kind wasn't specific enough. |
+ // The marker should encode the frame type. |
+ if (Smi::cast(marker)->value() > 100) { |
+ base::OS::DebugBreak(); |
+ } |
+ TRACE("MARKER = %d\n", Smi::cast(marker)->value()); |
return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
} |
@@ -1445,6 +1480,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) { |