| Index: src/frames.cc
|
| diff --git a/src/frames.cc b/src/frames.cc
|
| index 2ddb4200bfaedc450fa8db611711f64af717b771..76118dce23d6a40feaf1b97bc65c6d9570b2d5b7 100644
|
| --- a/src/frames.cc
|
| +++ b/src/frames.cc
|
| @@ -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) {
|
|
|